2011-06-19 25 views
15
私は複合主キー使って学生と教育コース間の多対多realationを作成しようとしている

マッピング多対多:

私のクラス:

@Entity 
@Table(name="Student_mtm_cId") 
public class Student { 

    private String id; 
    private Set<StudentTClass> teachingClasses = new HashSet<StudentTClass>(); 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.student") 
    public Set<StudentTClass> getTeachingClasses() { 
     return teachingClasses; 
    } 
    public void setTeachingClasses(Set<StudentTClass> teachingClasses) { 
     this.teachingClasses = teachingClasses; 
    } 

    public void addStudentToClass(TeachingClass teachingClass){ 
     StudentTClass studentTClass = new StudentTClass(); 
     studentTClass.setStudent(this); 
     studentTClass.setTeachingClass(teachingClass); 
     teachingClasses.add(studentTClass); 
    } 

    public void setLastName(String lastName) { 
     this.lastName = lastName; 
    } 

    @Id @GeneratedValue(generator="system-uuid") 
    @GenericGenerator(name="system-uuid", strategy = "uuid") 
    @Column(name = "student_id", nullable = false) 
    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    //all other setters and getters and isequal/hashCode omitted. 
} 

TeachingClass:

@Entity 
@Table(name="TechingClass_MTM") 
public class TeachingClass { 

    private String id; 
    private String name; 
    private String description; 
    private Set<StudentTClass> teachingClasses = new HashSet<StudentTClass>(); 

    public TeachingClass(){} 

    public TeachingClass(String name, String description) { 
     super(); 
     this.name = name; 
     this.description = description; 
    } 

    public void addStudentToClass(Student student){ 
     StudentTClass studentTClass = new StudentTClass(); 
     studentTClass.setStudent(student); 
     studentTClass.setTeachingClass(this); 
     teachingClasses.add(studentTClass); 
    } 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.teachingClass") 
    public Set<StudentTClass> getTeachingClasses() { 
     return teachingClasses; 
    } 

    public void setTeachingClasses(Set<StudentTClass> teachingClasses) { 
     this.teachingClasses = teachingClasses; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 

    @Id @GeneratedValue(generator="system-uuid") 
    @GenericGenerator(name="system-uuid", strategy = "uuid")  
    @Column(name = "teachingClass_id", nullable = false) 
    public String getId() { 
     return id; 
    } 

public void setId(String id) { 
     this.id = id; 
    } 
} 

コレクションオブジェクト:

@Entity 
@Table(name = "student_TClass_MTM") 
@AssociationOverrides({ 
@AssociationOverride(name = "pk.student", joinColumns = @JoinColumn(name = "student_id")), 
@AssociationOverride(name = "pk.teachingClass", joinColumns = @JoinColumn(name = "teachingClass_id")) 
     }) 
public class StudentTClass { 

    @EmbeddedId 
    private StudentTClassPK pk = new StudentTClassPK(); 

    public StudentTClassPK getPk() { 
     return pk; 
    } 

    public void setPk(StudentTClassPK pk) { 
     this.pk = pk; 
    } 

    public StudentTClass() {} 

    @Transient 
    public Student getStudent(){ 
    return this.pk.getStudent(); 
    } 

    @Transient 
    public TeachingClass getTeachingClass(){ 
    return this.pk.getTeachingClass();  
    } 

    public void setStudent(Student student){ 
     this.pk.setStudent(student); 
    } 

    public void setTeachingClass(TeachingClass teachingClass){ 
     this.pk.setTeachingClass(teachingClass);  
    } 

    } 

今PRIMARY KEY:

@Embeddable 
public class StudentTClassPK implements Serializable{ 

    private static final long serialVersionUID = -7261887879839337877L; 
    private Student student; 
    private TeachingClass teachingClass; 

    @ManyToOne 
    public Student getStudent() { 
     return student; 
    } 
    public void setStudent(Student student) { 
     this.student = student; 
    } 

    @ManyToOne 
    public TeachingClass getTeachingClass() { 
     return teachingClass; 
    } 
    public void setTeachingClass(TeachingClass teachingClass) { 
     this.teachingClass = teachingClass; 
    } 
    public StudentTClassPK(Student student, TeachingClass teachingClass) { 
     this.student = student; 
     this.teachingClass = teachingClass; 
    } 
    public StudentTClassPK() {} 


} 

私は学生を持続しようとしている私は、次のエラーを得た:私が間違って

Caused by: org.hibernate.MappingException: Could not determine type for: com.vanilla.objects.Student, at table: student_TClass_MTM, for columns: [org.hibernate.mapping.Column(student)] 
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:306) 
    at org.hibernate.tuple.PropertyFactory.buildStandardProperty(PropertyFactory.java:143) 
    at org.hibernate.tuple.component.ComponentMetamodel.<init>(ComponentMetamodel.java:68) 
    at org.hibernate.mapping.Component.buildType(Component.java:184) 
    at org.hibernate.mapping.Component.getType(Component.java:177) 
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:290) 
    at org.hibernate.mapping.RootClass.validate(RootClass.java:236) 
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1362) 
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1865) 
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:855) 
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:774) 
    at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417) 
    ... 51 more 

何をしているのですか?

答えて

13

私はこの問題を解決しました。フィールドの代わりにGetterをマップしました。

public class StudentTClass { 

    //@EmbeddedId 
    private StudentTClassPK pk = new StudentTClassPK(); 

    @EmbeddedId 
    public StudentTClassPK getPk() { 
     return pk; 
    } 
+0

これはうまくいった!私はEmbedabbleとしてタグ付けされたクラスだけでなく、EmbeddedIdタグを持つクラスの両方でこれを実行しなければなりませんでした。 –

5

可能であれば、私は真剣に複合キーを削除することをお勧めします。単純な主キーを使う価値は、多くの問題を解決してコードを単純化することができます。私はdbを変更する能力がなかったので、私は過去に複合キーをデータベースに使用してきました。残念ながら私はコードを持っていません。しかし、私はそれがすべて正しく動作するようにいくつかの作業が必要だったことを覚えています。申し訳ありません、より多くを助けることはできません。

+2

私はこの問題を解決しました。私のコードは今では完璧に動作します。これはHibernateに複合プライマリキーを使用させるのは難しいですが、多対多の関係では、コンビネーションごとに1つの行だけが確実に存在することを保証する必要がある特殊なケースでは便利です。 –

+2

私は、コンポジットキーが正当に有用なケースがあることに同意します。 – aroth

+2

@ danny.lesnik UNIQUEインデックスを使用して、一意性の組み合わせを保証することができます。 JPA 2.1は実装に依存しない構文を提供します。 –

関連する問題