简体   繁体   中英

JPA - Nothing happens after merge

Someone can tell me why nothing happens when I merge entity?

User.java (Entity)

@ManyToMany(mappedBy="users", targetEntity=Books.class,cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}) 
private List<Books> books;

Books.java (Entity)

@ManyToMany (targetEntity = User.class,cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
private List<User> users;

returnBookServlet.java

int userId = (int) session.getAttribute("userId");
String stringIdBook = request.getParameter("idBook");
UserDAO daoUser = (UserDAO) request.getAttribute("userDao");
User user = daoUser.getUser(userId);
List<Books> booksOrderedByUser = user.getBooks();

for (Books x : booksOrderedByUser) {
    String idBookString = Integer.toString(x.getIdBook());
    if (idBookString.equals(stringIdBook)) {
        booksOrderedByUser.remove(x);
        break;
    }
}

user.setBooks(booksOrderedByUser);
entityManager.getTransaction().begin();
entityManager.merge(user);
entityManager.flush();
entityManager.getTransaction().commit();
entityManager.close();

After and before foreach loop I display list via System.out.println() and it's correctly remove choosen book but nothing happen in database, what I did wrong?

The changes done in User entity are not synchronized with your data base because User entity is the non-owning side of your bidirectional ManyToMany relationship. You are using mappedby="users" in User entity, so the owner side is Book entity.

Your code should work if you change the owning side of your ManyToMany, in ManyToMany bidirectional relationships you can choose which side is your owning side (from JPA 2.1 specification):

Every many-to-many association has two sides, the owning side and the non-owning, or inverse, side. If the association is bidirectional, either side may be designated as the owning side. If the relationship is bidirectional, the non-owning side must use the mappedBy element of the ManyToMany annotation to specify the relationship field or property of the owning side.

Then, if you want to use the same code, change your anotations to:

User.java (Entity)

@ManyToMany(targetEntity=Books.class,cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}) 
private List<Books> books;

Books.java (Entity)

@ManyToMany (mappedBy="books",targetEntity = User.class,cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
private List<User> users;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM