Trong ứng dụng của tôi, tôi có các loại Hibernate ánh xạ (trường hợp chung):Tại sao Hibernate cố gắng xóa khi tôi cố gắng cập nhật/chèn?
class RoleRule {
private Role role;
private PermissionAwareEntity entity; // hibernate-mapped entity for which permission is granted
private PermissionType permissionType; // enum
@ManyToOne
@JoinColumn(name = "ROLE_ID")
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
class Role {
private Set<RoleRule> rules = new HashSet<RoleRule>(0);
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="ROLE_ID")
public Set<RoleRule> getRules() {
return rules;
}
public void setRules(Set<RoleRule> rules) {
this.rules = rules;
}
}
Tất cả các lớp có equals() & hashCode()
ghi đè.
Ứng dụng của tôi cho phép tinh chỉnh vai trò (chỉ bởi sysadmin, đừng lo lắng) và trong số các trường khác, cho phép tạo quy tắc vai trò mới. Khi một quy tắc mới được tạo, tôi cố tạo đối tượng RoleRule
mới và chèn nó vào trường của vai trò rules
. Tôi gọi session.update(role)
để áp dụng các thay đổi cho cơ sở dữ liệu.
Bây giờ đến phần xấu xí ... Hibernate quyết định làm như sau khi đóng cửa giao dịch và đỏ bừng:
- Chèn quy tắc mới vào cơ sở dữ liệu. Xuất sắc.
- Cập nhật các trường vai trò khác (không phải bộ sưu tập). Càng xa càng tốt.
- Cập nhật các quy tắc hiện tại, ngay cả khi không có gì thay đổi trong chúng. Tôi có thể sống với điều này.
- Cập nhật các quy tắc hiện tại lần nữa. Dưới đây là một dán từ nhật ký, trong đó có những nhận xét tự động:
/* delete one-to-many row Role.rules */ update ROLE_RULE set ROLE_ID=null where ROLE_ID=? and ROLE_RULE_ID=?
Tất nhiên, tất cả các lĩnh vực không phải là null, và hoạt động này không thành công ngoạn mục.
Có ai có thể cố gắng giải thích tại sao Hibernate lại làm điều này không ??? Và thậm chí quan trọng hơn, làm thế nào frak để tôi có được xung quanh này ???
EDIT: Tôi đã như vậy chắc chắn nó là cái gì để làm với các bản đồ, và sau đó ông chủ của tôi, trên một ý thích, xóa equals()
và hashCode()
trong cả hai lớp, tái tạo chúng bằng Eclipse, và một cách bí ẩn này đã giải quyết được vấn đề .
Tôi vẫn rất tò mò về câu hỏi của mình. Bất cứ ai có thể đề nghị tại sao Hibernate sẽ làm điều này?
Bạn đang sử dụng trình điều khiển và phương ngữ nào? –
ứng dụng đang chạy trên Oracle 10g, nhưng điều đó không quan trọng. – Yuval
Điều quan trọng nhất, việc thực hiện các phương thức 'equals' và' hashCode' bị thiếu trong bài viết của bạn. Xây dựng phương thức 'equals' và' hashCode' dựa trên giá trị nhận dạng cơ sở dữ liệu ** được tạo bởi hibernate hoặc cơ sở dữ liệu của bạn ** là một ý tưởng tồi, khiến chúng phụ thuộc vào bất kỳ trường nào có thể được cập nhật sau thời gian xây dựng thậm chí còn tồi tệ hơn. –