@ElementCollection @CollectionTable in One to Many mapping

38,069

Because both of your tables have their own ID columns, Hibernate will want them to both be @Entity types. @Embeddables do not have their own ID. So, first step is to change Course to be @Entity, with corresponding @TableName, etc.

This leads to the second issue, which is that the collection of Course objects shouldn't be an @ElementCollection, it should be a @OneToMany entity collection, with a @JoinColumn specifying that COLLEGE_ID will is the foreign key from TBL_COURSE.

Finally, by having a collection of Course in College, as well as a College id in Course, you are implying that you want a bidirectional association. Among other impacts of that, you should not have the ID of the college in Course. You should simply have the College reference. If you don't need to navigate from Course->College, you may want to remove that for now, until you've gained a better understanding of Hibernate's object mapping.

Share:
38,069
Rahul Shivsharan
Author by

Rahul Shivsharan

Updated on March 15, 2020

Comments

  • Rahul Shivsharan
    Rahul Shivsharan over 4 years

    I am trying relationship between in JPA using Embedded annotation, but i am not able to run it successfully,

    Here my Database sql Script is as follows,

    create table TBL_COLLEGE(
       id integer primary key generated always as identity (start with 1000, increment by 5),
       name varchar(50)
    )
    
    create table TBL_COURSE(
       Id  integer primary key generated always as identity (start with 10, increment by 1),
       college_Id integer references TBL_COLLEGE,
       name varchar(50)
    )
    

    here is the code below for JPA,

    @Embeddable
    public class Course {
    ...
    ...
    ..
    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    @Column(name="ID")
    private Integer courseId;
    
    @Column(name="NAME")
    private String courseName;
    
    @Column(name="COLLEGE_ID")
    private Integer collegeId;
    ....
    // getter and setter
    }
    

    Here is the College mapping,

    @Entity
    @Table(name="TBL_COLLEGE")
    public class College implements Serializable{
       @Id
       @GeneratedValue(strategy= GenerationType.IDENTITY)
       @Column(name="ID")
       private Integer collegeId;
    
       ...
       ..
       @ElementCollection(targetClass=Course.class,fetch= FetchType.LAZY)
       @CollectionTable(name="TBL_COURSE",joinColumns=@JoinColumn(name="COLLEGE_ID"))
       private Set<Course> course;
       ..
       // getter and setter
    }
    

    But if i try to persist College with Courses collection set, it gives me an exception,

    ERROR: HCANN000002: An assertion failure occurred (this may indicate a bug in Hibernate)
    org.hibernate.annotations.common.AssertionFailure: Declaring class is not found in the inheritance state hierarchy: com.entities.Course
    
    ....
    ..
    

    Can you please tell me whether my approach is wrong, Or my understanding for @CollectionTable is still minimal, Were i am going wrong

  • sharakan
    sharakan over 11 years
    That's fine, as long as you want Course to have it's lifecycle defined by College, and not be a standalone entity. You also won't be able to subclass Course, etc.
  • asch
    asch over 7 years
    Not necessary to define OneToMany annotation etc.. It is enough to remove ID annotation from the embedded class. Of course GeneratedValue annotation should be removed also.
  • sharakan
    sharakan over 7 years
    @asch - That is true, if you assume the OP didn't want Courses to be first class objects. Given the tables as defined though, removing the ID annotation would cause problems.
  • asch
    asch over 7 years
    Courses is already annotated as Embeddable, so it is not the Entity anyway (I guess you mean this by "the first class object")