2012-05-03 40 views
2

我有一個實體Player這個ID確定指標預設ID新建實體檢測爲「獨立實體」

@Id 
@GeneratedValue 
@Column(updatable=false) 
private long id; 

然而,有時(但不總是)我想與預設的ID創建一個新的實例。

player = new Player(...); 
player.setId(externalId); 
em.persist(player); 

這顯然導致Hibernate把它看作是一個離散的實體,拋出異常

org.hibernate.PersistentObjectException:通過分離的實體堅持

我怎樣才能避免這種情況?

回答

0

這裏有問題。你能告訴我們爲什麼你想要一個固定的ID嗎? 因爲你實際上說「請爲我創建一個ID我永遠不要想要處理這個」,那麼你有時試圖自己設置一個ID,這可能意味着你正在腐蝕整個事情。

該異常可能是因爲您正在設置已使用的ID。然後當試圖堅持時,hibernate檢測到它與DB中的內容不同步(分離),所以他只會拋出異常。

+0

我正在運行相同的服務器軟件兩次。在一個實例中,ID自動生成,但在另一個實例中,它們由外部提供(在這種情況下,由Facebook)。順便說一句,數據庫是空的,所以它不能是該ID已被使用。 –

+0

好的,那麼它是空的,你正在設置一個標記爲「自動生成」的ID,這意味着當你要求你的EM持續時,它會查看ID,如果爲null(未設置)它將生成一個新ID並堅持你的實體。如果不爲空,那麼它會在數據庫中查找相應的實體並進行更新(我認爲,對我來說這已經很長一段時間了,沒有Java:P)。所以,當你設置你的ID時,它會查找一個不存在的實體,並告訴你實體不同步。 (我想它假設你的實體已被刪除之間你所謂的「find()」和「persist()」或類似的東西) –

+1

Errm,「長」如何可以「未設置」(null)?它不能。它始終有一個值,無論是由編譯器還是由用戶應用。 – DataNucleus

1

我可以刪除@GeneratedValue和生成的ID我自己,是這樣的:

begin transaction 
if id not preset { 
    do { 
     id = random number 
    } while (id in use) 
} 
create player with id 
commit transaction 

這應該是安全的,與交易,但它比它讓數據庫成交不太理想。

+1

或將「long」更改爲Long。這然後允許空值(即未設置) – DataNucleus