2012-07-03 23 views
5

Vì vậy, tôi có bảng Người dùng, bảng Dự án và bảng Người dùng. Tôi có một người dùng được kết nối với 2 dự án, nhưng khi tôi chỉ có một vai trò cho anh ta thì nó trả về 2 dự án đó, nhưng nếu tôi có 2 vai trò cho anh ta thì nó trả về 4 vai trò (2x2 dự án). Làm thế nào để ngăn chặn điều nàyHibernate trả về trùng lặp vì một bảng khác có giá trị trùng lặp

này được mã của tôi trả lại danh mục dự án cho người dùng

@Override 
public List<Project> retrieve(User user) { 
    Criteria criteria = super.createCriteria(); 
    criteria.addOrder(Order.desc("date")); 
    criteria.createCriteria("users").add(Restrictions.eq("id", user.getId())); 

    return (List<Project>) criteria.list(); 
} 

ánh xạ trong lớp tài

@ManyToMany(cascade = CascadeType.ALL) 
@JoinTable(name = "Users_Projects", 
      joinColumns = @JoinColumn(name = "UserID"), inverseJoinColumns = @JoinColumn(name = "ProjectID")) 
public List<Project> getProjects() { 
    return projects; 
} 

@ElementCollection(fetch = FetchType.EAGER) 
@Enumerated(EnumType.STRING) 
@Column(name = "RoleType") 
@JoinTable(name = "User_Roles", joinColumns = @JoinColumn(name = "UserID")) 
public Set<Role> getRoles() { 
    return roles; 
} 

Mọi góp ý các vấn đề ở đây là gì?

tnx

Trả lời

13

cổ điển "sửa chữa" cho các vấn đề của các hàng trùng lặp từ tiêu chí truy vấn, trong đó có khả năng sẽ làm việc miễn là bạn không cố gắng để kết hợp nó với pagination, là thêm

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 

Tôi tin rằng điều này đang xảy ra trong tình huống của bạn vì tải trọng háo hức của vai trò người dùng. Thay đổi điều đó là lười biếng cũng có thể hiệu quả và tiếp tục hoạt động nếu bạn cần phân trang.

Đặt fetch = FetchType.EAGER hướng dẫn ngủ đông mà bạn muốn luôn tải tất cả các vai trò cho người dùng bất cứ khi nào bạn truy xuất người dùng, nó hoàn thành bằng cách luôn tham gia vào bảng vai trò. Thật không may, sql đó dẫn đến nhiều bản ghi với cùng một người dùng (một cho mỗi vai trò), và sau đó nó phải được làm thẳng ra trong Java sau khi chạy sql, đó là những gì biến thế kết quả thực hiện. Quay lại đầu trang ||||||||||||||||||||||||||||||||||||||||| Nếu bạn muốn sử dụng phân trang theo cách tự nhiên nhất với các tiêu chí ngủ đông đơn giản, sử dụng criteria.setFirstResultcriteria.setMaxResults, mọi thứ xảy ra theo thứ tự sai, vì vậy các truy vấn này cần biến thế kết quả để tránh trùng lặp chỉ cần 'don' t trang phải.

Để hiểu tất cả các thế hệ sql hibernate tốt hơn một chút, tôi khuyên bạn nên bật ghi nhật ký sql đã tạo như được mô tả trong this answer sang câu hỏi SO ngủ đông khác.

+1

cảm ơn bạn! làm việc như một say mê, tuy nhiên bạn có thể giải thích lý do tại sao việc tải các vai trò dẫn đến điều này. Tôi cũng chắc chắn rằng đây là trường hợp, nhưng tôi chỉ không làm theo lý do tại sao sẽ thiết lập một cái gì đó mà không phải là một phần của kết nối của người sử dụng các dự án gây ra điều này. Có suy nghĩ gì không? –

+0

Xem cập nhật của tôi để biết thêm một chút về câu hỏi trong nhận xét của bạn. –

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