Java – hibernate bi directional many to many association creation duplication

My question is very similar to the hibernate bi directional manytomany updates with second level cache

I have class, as shown below

@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Entity 
public class A{
     private int id;
     private List<B> listB;

     ...
     @Cache (usage = CacheConcurrencyStrategy.TRANSACTIONAL)
     @ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE},targetEntity = B.class)
     @JoinTable(name = "A_B",joinColumns = { @JoinColumn(name = "a_id") },inverseJoinColumns = { @JoinColumn(name = "b_id") })
     public List<B> getListB() {
         return listB ;
     }
}

@Cache (usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@Entity
public class B{
     private int id;
     private List<A> listA;

     @ManyToMany(cascade = {CascadeType.PERSIST,targetEntity = A.class)
     @JoinTable(name = "A_B",joinColumns = { @JoinColumn(name = "b_id") },inverseJoinColumns = { @JoinColumn(name = "a_id") })
     public List<a> getListA() {
         return listA ;
     }

     public void addToA(A a) {
         a.getListB().add(this);
     }
}

As expected for many - to - many relationships, I have been updating two aspects of a two - way relationship

Now the problem I have is that when I try to add / update items in the collection, duplicate entries pop up The following is the code I use to persist entities

b.getA().clear() ;
...
...
b.getListA().add(A) ;
b.addToA(A) ;
em.saveOrUpdate(b) ;

The following is the query obtained by hibernate from the log

delete from A_B where b_id=?

insert into A_B (b_id,a_id) values (?,?)
insert into A_B (b_id,?)

delete from A_B where a_id=?

insert into A_B (a_id,b_id) values (?,?)
insert into A_B (a_id,?)

Where was I wrong? How do I get rid of duplicates being inserted? The cache is being refreshed correctly, but duplicate entries are the only problem!

Solution

This is a classic!

The problem is that both of your mappings are owners. One should be the owner and the other should be reverse Because both are owners, changes to them will cause the database to be inserted; There is an owner and an inverse, with only one set of inserts

You should be able to rewrite B:: getlista to:

@ManyToMany(cascade = {CascadeType.PERSIST,mappedBy = "listB")
 public List<A> getListA()

Let everything go smoothly

Please note that only the owner is used as the @ jointable annotation Typically, any given location in a database is mapped to a location in a JPA application If you find yourself mapping twice, take a moment to see if there is a better way

By the way, you don't need the targetentity attribute; JPA providers can solve this problem from generics

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>