2009-04-09 22 views
17

Tôi nhận được ngoại lệ sau khi tôi đang cố gắng thay đổi @ID của mình trong một @Entity.Hibernate, thay đổi số nhận dạng/khóa chính

identifier of an instance of com.google.search.pagerank.ItemEntity was altered from 1 to 2. 

Tôi biết rằng tôi đang thay đổi khóa chính trong bảng của mình. Tôi đang sử dụng chú thích JPA.

tôi giải quyết điều này bằng cách sử dụng này truy vấn HQL duy nhất: update Table set name=:newName where name=:oldName

Thay vì sử dụng cách tiếp cận OO hơn:

beginTransaction(); 
T e = session.load(...); 
e.setName(newName); 
session.saveOrUdate(e); 
commit(); 

Bất cứ ý tưởng gì khác là gì?

+0

Bạn đang cố gắng sử dụng một pháp nhân khác làm PK? –

+0

bây giờ tôi đang cố gắng thay đổi khóa riêng của tôi từ một thực thể kiên trì. trong sql nó sẽ là một cái gì đó như: "Cập Nhật Khách hàng thiết lập customerId = 1492 nơi customer_id = 42;" và customer_id là khóa riêng của tôi – Schildmeijer

Trả lời

10

Tôi không thể tưởng tượng tại sao bạn muốn làm điều đó. Ở tất cả. Tại sao bạn thay đổi danh tính của một thực thể? Bạn cũng cần phải cập nhật tất cả các khóa ngoài trong các bảng khác trỏ đến nó. Có vẻ như một nỗi đau, không có được. Có lẽ bạn nên làm điều này là "chìa khóa kinh doanh" (tài sản đồng bằng) và sử dụng khóa thay thế vĩnh viễn hơn. Tôi có một cảm giác rằng bạn đang đi về điều này tất cả sai, nhưng nếu bạn nhấn mạnh ...

Về cơ bản những gì bạn đang làm là tạo một Khách hàng mới và xóa khách hàng cũ, và đó là cách tôi hoàn thành nó trong Hibernate.

[giả]

Begin Transaction 

// create new customer from old 
newC = Session.Load<Customer>(42) 
Session.Evict(newC) 
newC.Id = 1492 
Session.Save(newC) 

// update other relationships to point to newC 
// .... 

// delete old customer 
oldC = Session.Load<Customer>(42) 
Session.Delete(oldC) 

Commit Transaction 

Tuy nhiên, bạn có lẽ tốt hơn hết chỉ cần làm việc đó trong tất cả cùng một lúc trong một giao dịch SQL đơn giản, và trong cả hai trường hợp bạn có nguy cơ có các quá trình song song đã có một ví dụ của Khách hàng "cũ", có thể gây ra một số lỗi.

+5

Trước hết; không có ràng buộc khóa ngoại nào đối với danh tính này. Và ofcourse có những tình huống khi một người muốn thay đổi khóa chính. Tôi có thể thừa nhận rằng đó không phải là điều bạn làm mỗi ngày, nhưng bối cảnh có thể không có bất kỳ nghi ngờ nào tạo ra một tình huống có thể giải quyết nó. – Schildmeijer

+0

Mặc dù tôi không thể * tưởng tượng * một kịch bản như vậy, tôi thừa nhận rằng một kịch bản có thể tồn tại. Tôi sẽ * yêu * để biết kịch bản này là gì. Ngoài ra, bất kỳ suy nghĩ về các giải pháp đề xuất? –

+0

ý định của tôi không phải là thô lỗ. kịch bản của tôi là một cái gì đó như thế này. Tôi có một bảng với hai cột, nick :: string và number :: int, trong đó nick là khóa chính. Và vì những hạn chế về bộ nhớ nhúng, chúng tôi không thể đủ khả năng để thêm một id như nickId. Và mọi người được phép thay đổi nick – Schildmeijer

3

Bạn tôi, bạn đã đúng. Không có cách nào (hoặc tôi không biết một cách nào) để thay đổi khóa chính mà không sử dụng các câu lệnh HQL. Nó không bình thường, nhưng đó là sự thật.

21

Trên thực tế, theo các đặc điểm kỹ thuật JPA không được phép thay đổi một khóa chính:

Ứng dụng này không phải thay đổi giá trị của khóa [8] chính. Hành vi không xác định nếu điều này xảy ra. [9]

(từ EJB 3 kiên trì (JPA) đặc điểm kỹ thuật, đoạn 2.1.4)

+0

Tôi không thể tìm thấy điều này trong phiên bản cuối cùng. –

3

Đây không phải là một giải pháp, như tôi tin rằng đã được trả lời ở trên.

Tuy nhiên, tôi muốn cung cấp những gì tôi coi là một kịch bản hợp lệ để thực hiện việc này. (Cảm nhận chào đón)

1) Bảng USER_ELECTRONICS có nhiều-nhiều với bảng ELECTRONICS_DEF

2) Điều này nhiều-nhiều là một danh sách đặt hàng. Mỗi USER_ELECTRONIC_ID có danh sách ưu tiên là ELECTRONICS_DEF_ID. Ví dụ, tôi có một IPhone, một IPad, Cell Phone, và tôi xếp hạng chúng theo thứ tự tôi thích chúng.Để thực hiện điều này, tôi có bảng USER_ELEC_PRIORITY_MAP, trông như thế này -

USER_ELEC_IDELEC_DEF_IDPRIORITY

1IPAD1
1IPHONE2
1CELL3

USER_ELEC_ID, và ELEC_DEF_ID là PFKs. PRIORITY là Composite FK.

3) Khi tôi muốn mã hóa lại bảng theo sở thích của mình (IPad2 mới của tôi nằm trong danh sách và iPad di chuyển đến # 4), tôi cần cập nhật một phần của Composite FK (PRIORITY).

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