2012-01-12 37 views
6

Tôi rất mới vào mùa xuân và tôi đang cố gắng tạo ra một mối quan hệ nhiều-nhiều, như tôi mong đợi. Các mối quan hệ hoạt động tốt, các bảng được tạo ra và dữ liệu được chèn chính xác. Điều tôi mong đợi, là khi tôi xóa một Danh sách (nghĩa là tôi xóa sạch người dùng "ArrayList" khỏi một đối tượng thuộc loại "Nhóm"), tôi mong đợi hệ thống xóa các mối quan hệ khỏi cơ sở dữ liệu - nhưng không.Spring + JPA có nhiều mối quan hệ với nhau

Tôi đã các lớp sau:

@Entity 
@Table(name = "`group`") 
public class Group 
{ 
    @Id 
    @GeneratedValue 
    @Column(name = "id") 
    private int id; 

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

    @ManyToMany(cascade = {CascadeType.ALL}) 
    @JoinTable(
      name = "`user_has_group`", 
      joinColumns = @JoinColumn(name = "group_id", referencedColumnName = "id"), 
      inverseJoinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id") 
    ) 
    private List<User> users = new ArrayList<User>(); 

    ... 
} 

@Entity 
@Table(name = "`user`") 
public class User 
{ 
    @Id 
    @GeneratedValue 
    @Column(name = "id") 
    private int id; 

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

    @ManyToMany(mappedBy = "users") 
    private List<Group> groups = new ArrayList<Group>(); 

    ... 
} 

Dưới đây là DAO:

@Repository 
public class GroupJpaDao implements GroupDao 
{ 
    private EntityManager em; 

    @Transactional 
    public void save(Group group) 
    { 
     this.em.merge(group); 
    } 

    ... 

    @PersistenceContext 
    void setEntityManager(EntityManager entityManager) 
    { 
     this.em = entityManager; 
    } 
} 

@Repository 
public class UserJpaDao implements UserDao 
{ 
    private EntityManager em; 

    @Transactional 
    public void save(User user) 
    { 
     this.em.merge(user); 
    } 

    ... 

    @PersistenceContext 
    void setEntityManager(EntityManager entityManager) 
    { 
     this.em = entityManager; 
    } 
} 

Dưới đây là phương pháp kiểm tra:

@Test 
public void test() 
{ 
    Group g = new Group(); 
    g.setName("Test group"); 
    groupDao.save(g); // Works fine - inserts the group into the database 

    User u = new User(); 
    u.setName("Test user"); 
    userDao.save(u); // Works fine - inserts the user into the database 

    g.addUser(u); 
    groupDao.save(g); // Works fine - adds the many-to-many relationship into the database 

    g.removeAllUsers(); 
    groupDao.save(g); // Doesn't work - I'm expecting it to remove all the related relationships from the database but it doesn't! 
} 

Tôi có làm sai điều gì hoặc là nó một cái gì đó không thể làm gì?

Bất kỳ gợi ý nào thực sự được đánh giá cao.

Cảm ơn bạn!

+0

bạn đã thử thêm 'xóa-mồ côi' vào thuộc tính' tầng' của bạn? – fasseg

+0

Bạn đã khai báo 'IdTransferringMergeEventListener' chưa? – axtavt

+0

Không biết nếu đó là nguyên nhân của vấn đề, nhưng phương pháp lưu không nên trả về void. Nó sẽ trả về kết quả của cuộc gọi hợp nhất. Hãy thử thực hiện thay đổi này và sử dụng nhóm được trả về: 'g = groupDao.save (g); ' –

Trả lời

2

Tôi đọc lại câu hỏi của bạn và bây giờ câu trả lời là rõ ràng. Tạo một Nhóm g và lưu nó. Nhưng vì phương pháp lưu của bạn sử dụng merge và bạn không tính đến giá trị được trả lại bởi merge để gán giá trị đó cho g, bạn tiếp tục hợp nhất nhóm tạm thời g, không bao giờ có bất kỳ ID nào được chỉ định. Vì vậy, mỗi lần hợp nhất được gọi, bạn thực sự tạo một nhóm mới thay vì sửa đổi nhóm đã tạo trước đó.

Thay đổi phương pháp tiết kiệm để

public Group save(Group group) 
{ 
    return this.em.merge(group); 
} 

và luôn phân công lại kết quả để g:

g = groupDao.save(g); 

Tất nhiên, cùng phải được thực hiện cho người dùng.

+0

Cảm ơn bạn rất nhiều, điều này đã giải quyết được vấn đề! – satoshi

0

bạn chỉ xóa người dùng khỏi nhóm, điều đó là chưa đủ. bạn cần xóa tất cả người dùng khỏi nhóm và xóa nhóm đó khỏi tất cả các nhóm của những người dùng đó.

+0

Không cần thiết, vì bên sở hữu là nhóm. –

+0

bạn có chắc chắn không? sau cùng thì nó cũng rất nhiều. satoshi, bạn có thể thử cái này được không! tôi phải thừa nhận tôi đã không kiểm tra nó trước:/ – davogotland

+0

Vâng, tôi chắc chắn. Tài liệu nói: "Nếu hiệp hội là hai chiều, một bên phải là chủ sở hữu và một bên phải là đầu nghịch đảo (tức là nó sẽ bị bỏ qua khi cập nhật các giá trị mối quan hệ trong bảng kết hợp):" –

Các vấn đề liên quan