Search code examples
hibernatehibernate-mappingcomposite-primary-key

@SecondaryTable Mapping from primary table (compsite primary key) to secondary table (single primary key)


Table :person

id (pk)  
first_name  
last_name

Entity:

@Entity
@Table(name="person")
public class Person {

    @Id
    @Column(name="id")
    private String id;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

    @Column(name="birthDate")
    private String birthDate;

    @Column(name="detail")
    private String detail;
}

Table :activity

id(pk)
name;

Entity:

@Entity
@Table(name="activity")
public class Activity {

    @Id
    @Column(name="id")
    private String id;

    @Column(name="name")
    private String name;

    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinColumn(name="activity_id")
    private List<PersonRole> personRoleList;
}

Table :person_role

activity_id 
person_id 
role_name
pk(activity_id,person_id)

Entity:

@Entity
@Table(name="person_role")
public class PersonRole {


        @Id
        PersonRolePK personRolePk;


    //  private String personName; /* I want this value to be loaded form person table using the person_id when a PersonRole is reader from database */


        @Column(name="role_name")
        private String roleName;

}


@Embeddable
public class PersonRolePK implements Serializable
{
    public static final long serialVersionUID = 1L;

    @Column(name="activity_id")
    public String activityId;

    @Column(name="person_id")
    public String personId;

}

This is working well for me when i am storing data in database

It also work as expected and load all related PersonRole when i want to the Activity from database

Now in Addition I want to fill the personName field of class PersonRole(commented) from the table person when the PersonRole is being loaded.

I read about @SecondaryTable annotation and approached with it.

But the problem is all the tutorials and documentations also this http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#d0e2235) show that it is necessary to have the same number of primary key field (if composite key) in both of the table if i want to map the secondary table and those filed will be mapped using @PrimaryKeyJoinColumn

But in my case there is no need to use multiple key as the Person has single primary key

So Is there any way to map a table containing composite primary key to with table containing single primary key to use @SecondaryTable?

OR,

Is there any other good approach to achieve what i want.?


Solution

  • Normally in this situation I would have a OneToMany relationship in the Activity and Person pojo's. And in the PersonRole pojo you would have a ManyToOne relationship for each of Activity and Person, which lets you get at all the data you need without duplicating of data (personname).

    Add a OneToMany in the Person pojo.

    Set<PersonRole> personRoles = new HashSet<PersonRoles>();
    
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "person")
    public Set<PersonRole> getPersonRoles() {
       return this.personRoles;
    }
    public void setPersonRoles(Set<PersoneRole> personRoles) {
       this.personRoles = personRoles;
    }
    

    Add a ManyToOne relationship in the PersonRole pojo.

    Private Person person;
    Private Activity activity;
    
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "person_id")
    public Person getPerson() {
       return this.person;
    }
    public void setPerson(Person person) {
       this.person = person;
    }
    
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "activity_id")
    public Activity getActivity() {
       return this.activity;
    }
    public void setActivity(Activity activity) {
       this.activity = activity;
    }
    

    You should now be able to get the name out of Person when querying on Activity.