Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a separate Primary Key to a Join Table in Hibernate

I have a question about Hibernate ManyToMany mappings. I have two classes A and B and the mapping between them is a ManyToMany mapping resolved by Hibernate:

@Entity
@Table(name="A")
public class A {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToMany
    @JoinTable(name="C", joinColumns=@JoinColumn(name="a_id"), inverseJoinColumns=@JoinColumn(name="b_id"))
    private Set bs;
}

@Entity
@Table(name="B")
public class B {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToMany(mappedBy="bs")
    private Set bs;
}

As you can see, the Join Table I use is C. The foreign keys to A and B are "a_id" and "b_id". My understanding is, that Hibernate creates a composed Primary Key with a_id and b_id for table C.

I don't want to have an entity C in my model. But instead of a composed primary key on table C, I would like to have a generated ID and a unique constraint on the fields a_id and b_id.

Is it possible to tell Hibernate to use a separate primary key? Without adding an entity C?

I would appreciate any help.

Thanks a lot!

like image 840
BHulliger Avatar asked Sep 21 '10 16:09

BHulliger


3 Answers

You should do iyt like this. But it can be appled only for list (not for sets)

@Entity
@TableGenerator(name="ids_generator", table="IDS")
public class Passport {
    ...

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="PASSPORT_VISASTAMP")
    @CollectionId(
        columns = @Column(name="COLLECTION_ID"), 
        type=@Type(type="long"), 
        generator = "ids_generator"
    )
    private Collection<Stamp> visaStamp = new ArrayList();
    ...
}
like image 96
Igor Avatar answered Nov 16 '22 17:11

Igor


I don't think it is possible. And I don't see a problem in defining a C entity.

If you have any additional information ind the join-table, it will not be accessible to you, because your Set contains the target entity - A or B.

Also, your Sets would better make use of generics - i.e. Set<A> and Set<B>.

Btw, Hibernate might not be alarmed by the fact that the table creates another entity - using your current mapping might work (disregarding completely the id column). When you said "Hibernate creates", I assumed you are generating your schema from your entity model. Now it seems it's the opposite, so give it a try.

like image 41
Bozho Avatar answered Nov 16 '22 19:11

Bozho


But instead of a composed primary key on table C, I would like to have a generated ID and a unique constraint on the fields a_id and b_id.

Normally the primary key of the JoinTable is made of the combination of both foreign keys. At least, this is what JPA would generate. But if you don't use the JPA provider to generate the model and if the PK can be generated by the database (using an IDENTITY column, a trigger, etc), then you should be able to use the C table for your ManyToMany association (without having to introduce an extra entity and to transform the relation in two OneToMany). Did you actually try?

like image 1
Pascal Thivent Avatar answered Nov 16 '22 18:11

Pascal Thivent