Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate Jpa Annotation: Problem with Embedded Id

I have this schema of db:

Table_A[1]-->[n]Table_C and Table_B[1]-->[n]Table_C

Now, the PrimaryKey of Table_C is a EmbeddedId with Foreign key versus Table_A and Foreign Key versus Table_B. How do I note this annotation?

My solution is:

@Entity
public class TableA{
    @Id @column(name="ID")
    public int id;

    @OneToMany(mappedBy="tableA")
    public List<TableC> listOftableC; 
}

@Entity
public class TableB{
    @Id @column(name="ID")
    public String id;

    @OneToMany(mappedBy="tableB")
    public List<TableC> listOftableC; 

}

@Entity
public class TableC{
    @EmbeddedId
    public TableCPK idComposite;
}

@Embeddable
public class TableCPK{

    @ManyToOne
    @JoinColumn(name = "ID_TABLE_A", referencedColumnName="ID")
    public TableA tableA;

    @ManyToOne
    @JoinColumn(name = "ID_TABLE_B", referencedColumnName="ID")
    public TableA tableB;
}
like image 289
giulius Avatar asked Jul 06 '11 10:07

giulius


1 Answers

When you follow the JPA spec, you will note that there is no need to map tableC. You can just use a jointable

Something like this

@Entity
public class TableA{
    @Id
    @column(name="ID")
    public int id;
    @ManyToMany
    @JoinTable(name="TableC",
            joinColumns = {@JoinColumn(name = "ID_TABLE_A", referencedColumnName="ID")},
            inverseJoinColumns = {@JoinColumn(name = "ID_TABLE_B", referencedColumnName="ID")
    })
    public List<TableB> listOftableB;
}
@Entity 
public class TableB{
     @Id @column(name="ID")
     public String id;
     @OneToMany(mappedBy="listOftableB")
     public List<TableA> listOftableA;
}

if you want to map something in the JoinTable you can also define it as an Entity. You can map tableC like this

@Entity
public class TableC{
    @EmbeddedId
    private MyId id;
    @ManyToOne
    @JoinColumn(name = "ID_TABLE_A", insertable = false, updatable = false)
    private TableB tableA;
    @ManyToOne
    @JoinColumn(name = "ID_TABLE_B", insertable = false, updatable = false)
    private TableB tableB;

    @Column(name="extra_field")
    private String extraField;
}

@Embeddable
public class MyId{
    @Column(name="ID_TABLE_A")
    private int idTableA;
    @Column(name="ID_TABLE_B")
    private int idTableB;
    // equals, hascode,...
}

By making the objects insertable/updatable false, you can map the same properties multiple times. The other properties in the id are offcourse not updatable, because you would break your pk.

like image 107
jelle Avatar answered Sep 22 '22 16:09

jelle