2009-07-09 39 views
5

Tôi có đối tượng người dùng có quan hệ một-nhiều với các loại Chuỗi. Tôi tin rằng họ là ánh xạ đơn giản. Bảng loại chứa tên user_id và tên biến có liên quan, với khóa chính là 'id' mà về cơ bản là một bộ đếm.Hibernate Lưu hành vi lạ

<class name="Users" table="users"> 
    <id column="id" name="id" /> 
    ... 
    <set name="types" table="types" cascade="save-update"> 
     <key column="id" /> 
     <one-to-many class="Types" /> 
    </set> 
</class> 

<class name="Types" table="types"> 
    <id column="id" name="id" /> 
    <property column="user_id" name="user_id" type="integer" /> 
    <property column="type" name="type" type="string" /> 
</class> 

Đây là java tôi sử dụng để thêm vào cơ sở dữ liệu:

User u = new User(); 
u.setId(user_id); 
... 
Collection<Types> t = new HashSet<Types>(); 
t.add(new Type(auto_incremented_id, user_id, type_name)); 
u.setTypes(t); 

getHibernateTemplate().saveOrUpdate(u); 

Khi tôi chạy nó, nó mang lại cho lỗi này:

61468 [http-8080-3] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 1062, SQLState: 23000 
61468 [http-8080-3] ERROR org.hibernate.util.JDBCExceptionReporter - Duplicate entry '6' for key 'PRIMARY' 
61468 [http-8080-3] ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session 
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update 

Khi tôi kiểm tra sql, nó hiển thị:

Hibernate: insert into users (name, id) values (?, ?) 
Hibernate: insert into types (user_id, type, id) values (?, ?, ?) 
Hibernate: update types set id=? where id=? 
  • Tại sao Hibernate cố gắng cập nhật id loại?

Lỗi nói: Mục nhập trùng lặp '6' cho khóa 'CHÍNH', ​​nhưng có thực sự không? Tôi đảm bảo rằng các id được tăng lên mỗi lần. Và người dùng và các loại được thêm vào cơ sở dữ liệu chính xác.

Tôi đã đăng nhập thông tin và các loại được thêm có id là 7 và id người dùng là 6. Có thể Hibernate lấy user_id là 6 và cố gắng cập nhật các loại và đặt id = 6 trong đó id = 7? Do đó, lỗi khóa chính trùng lặp?

Nhưng tại sao nó lại làm điều gì đó kỳ lạ? Có cách nào để ngăn không cho cập nhật không?

  • Tôi có nên đặt id theo cách thủ công không? Nếu không, thì tôi nên thêm các loại như thế nào? Nó cho các lỗi khác khi tôi thêm một đối tượng kiểu chỉ có một chuỗi kiểu trong đó và không có id.

Xin cảm ơn các bạn. Đã nghiền ngẫm nó trong nhiều ngày ...

Trả lời

2

Vấn đề lớn nhất của bạn là cột không chính xác trong ánh xạ <key> - nó phải là "user_id", không phải là "id". Điều đó nói rằng, toàn bộ bản đồ của bạn có vẻ hơi lạ với tôi.

Trước hết, nếu bạn muốn ID tự động tạo bạn thực sự nên để Hibernate chăm sóc đó bằng cách xác định máy phát điện phù hợp:

 
<id column="id" name="id"> 
    <generator class="native"/> 
</id> 

đọc Hibernate Documentation trên máy phát điện cho các tùy chọn có sẵn khác nhau.

Thứ hai, nếu tất cả các bạn cần là một tập hợp của các loại chuỗi, hãy xem xét lại lập bản đồ chúng vào một tập hợp các yếu tố chứ không phải là một-nhiều mối quan hệ:

 
<set name="types" table="types"> 
    <key column="user_id"/> 
    <element column="type" type="string"/> 
</set> 

Bằng cách đó bạn sẽ không cần rõ ràng "Loại" lớp hoặc ánh xạ cho nó. Ngay cả khi bạn muốn có thuộc tính bổ sung trên "Loại", bạn vẫn có thể ánh xạ nó thành thành phần thay vì thực thể.

Cuối cùng, nếu "Các loại" phải là một thực thể do một số yêu cầu bạn đã không được mô tả, mối quan hệ giữa "Người dùng" và "Các loại" là bi-directional và cần phải được ánh xạ như vậy:

 
<set name="types" table="types" inverse="true"> 
    <key column="user_id"/> 
    <one-to-many class="Types"/> 
</set> 

... 
in Types mapping: 
<many-to-one name="user" column="user_id" not-null="true"/> 

Trong trường hợp thứ hai "Loại" sẽ phải có thuộc tính "người dùng" của loại "Người dùng". Here là ví dụ chi tiết.

+0

Bị mắc kẹt với bộ sưu tập của các yếu tố! Cảm ơn! – April

0

Các giải pháp mà làm việc cho tôi là để cứu riêng hai bộ phận (mà không cần thêm loại cho người sử dụng):

getHibernateTemplate().save(user); 
getHibernateTemplate().save(new Type(user.id, type_name)); 

Và với < lớp phát = "mẹ đẻ" /> trên chỉ có các loại id.

Thực hành không tốt?

Đã ánh xạ nó dưới dạng tập hợp các phần tử, nhưng có phần sai khi thêm user_id vào cột id loại gây ra lỗi trùng lặp đôi khi; vì id loại là cột khóa chính duy nhất. Kỳ dị! Tôi nhớ có một số lỗi cột khác, nhưng quên nó, bởi vì tôi ngay lập tức quay trở lại một-nhiều. Không thể nắm bắt các hoạt động kỳ lạ của Hibernate ...

tôi sẽ cố gắng giải pháp hai chiều đôi khi ... Cảm ơn rất nhiều cho tất cả sự giúp đỡ :)

+1

Tôi e rằng bạn đang thiếu điểm hoàn toàn. Bạn nên để Hibernate làm cho cuộc sống của bạn dễ dàng hơn, không phải chiến đấu với nó từng bước của con đường - và có ánh xạ chính xác sẽ đi một chặng đường dài để đạt được điều đó. Kịch bản bạn đã mô tả ở trên rất cơ bản; có rất nhiều ví dụ có sẵn (tôi đã đăng các liên kết trong câu trả lời của mình). Bạn thực sự cần phải đọc qua tài liệu, làm việc này và hiểu _how_ nó hoạt động; nếu không nó sẽ khó hơn rất nhiều trên đường. – ChssPly76

+0

Có, tôi biết nó rất cơ bản, vì vậy tôi bối rối vì sao nó vẫn bị phá vỡ. Sử dụng giải pháp này, hibernate cố gắng tìm kiếm các loại bằng cách kết hợp loại id thành user_id, điều này hoàn toàn lạ. Vì vậy, tôi đã thực hiện bộ sưu tập các yếu tố được đề cập ở trên và hiện đang gặp lỗi lớp học. Làm cho ánh xạ cho Hibernate khiến cuộc sống trở nên khó khăn! Mỗi khi có bản đồ, chúng không theo dõi cách thức các đối tượng có thể được truy cập hoặc truy xuất. Bạn phải tìm kiếm và đào xung quanh một số nơi khác. – April