我有一個用戶實體,它使用用戶提供的電子郵件地址作爲主鍵而不是自動生成的值。這意味着當調用JpaRepository的保存方法時,主鍵值是非空。彈簧數據JPA不允許實體在主鍵不爲空時被保留
春數據JPA documentation2.2.1節表2.2說以下內容:
缺省時,Spring數據JPA檢查給定 的實體的ID屬性。如果Id屬性爲空,則該實體將被假定爲 新的,否則不是新的。
此行爲阻止將新的訂購者實體持久保存到數據庫。
我有一個用戶實體,它使用用戶提供的電子郵件地址作爲主鍵而不是自動生成的值。這意味着當調用JpaRepository的保存方法時,主鍵值是非空。彈簧數據JPA不允許實體在主鍵不爲空時被保留
春數據JPA documentation2.2.1節表2.2說以下內容:
缺省時,Spring數據JPA檢查給定 的實體的ID屬性。如果Id屬性爲空,則該實體將被假定爲 新的,否則不是新的。
此行爲阻止將新的訂購者實體持久保存到數據庫。
The same table告訴您如何自定義該行爲。
要麼讓您的實體執行Persistable
並覆蓋isNew
,要麼提供EntityInformation
的自定義實現。
當談到決定如何選擇實體的主鍵時,我們有兩個選擇。 1.使用Spring 提供的自動生成的密鑰2.使用自定義主鍵,例如電子郵件地址。
自動生成的密鑰更易於使用。當堅持實體時,Spring注意到id字段爲空,並得出結論:這是一個新的實體被持久化。一個新的自動生成的值被分配給id字段,並且該實體被持久化。但是,如果您要確保具有相同電子郵件地址的兩個實體未被保留,請記住使用@Column(unique="true")
註釋電子郵件字段。由於電子郵件字段的唯一限制,檢測重複郵件也很容易。
但是,有時您不想使用自動生成的密鑰,因爲您可能希望使用用戶提供的電子郵件地址作爲密鑰。這種方法沒有問題。用@Id標記實體中的電子郵件字段。就這樣。但是,重複檢測是不可能的。如果多次接收到創建具有相同電子郵件地址的實體的請求,則每次都會更新同一個實體,即每次都會執行EntityManager.merge()
。違反約束的異常將不會被引發。回想一下,Spring總是檢查主鍵字段是否爲空,以決定是創建新實體還是合併到現有實體中。
它不應該。由於回購看到ID存在於輸入實體中,它將在內部調用'EntityManager.merge()',它仍應該保存您的實體。你只需要記住把'repository.save()'的返回值作爲被管實體 –
@AdrianShum你是對的。它現在有效。但是,沒有檢測到重複項目。如果我嘗試保存同一個實體兩次,第二次它不會像我使用自動生成的密鑰一樣給出重複的異常。相同的實體更新,這不是我想要的。 – Amit