2016-06-09 115 views
0

我遇到了一個問題,即hibernate多次存儲相同的密鑰。例如,假設我有一個主鍵爲「堆棧溢出」的對象。我用相同的主鍵「堆棧溢出」創建另一個對象,hibernate將保存兩個對象,每個對象都有自己的記錄。我個人認爲這是由uuid引起的,因爲「堆棧溢出」不會出現在數據庫中兩次,但每個對象的唯一uuid不同。我如何修復爲字符串生成不同的uuid?休眠使用uuid時生成重複的主鍵

用戶類,電子郵件字段按預期工作,不允許重複的電子郵件。

@Entity 
@Table(name = "Users") 
public class User { 

    @Id 
    @GeneratedValue(generator = "uuid") 
    @GenericGenerator(name = "uuid", strategy = "uuid2") 
    private String username; 

    @Column(unique = true) 
    private String email; 

    private String password; 
    private String firstName; 
    private String lastName; 

    // Getters and Setters 

表數據

+--------------------------------------+-------------------------+-----------+----------+----------+ 
| username        | email     | firstName | lastName | password | 
+--------------------------------------+-------------------------+-----------+----------+----------+ 
| 2afcb68b-e7e2-4b7d-bb8e-c886b34092aa | [email protected]   | charlie | sexton | sexton | 
| 365a64b0-e036-4654-ad3a-afe2440f5b37 | [email protected]   | charlie | sexton | sexton | 
| 9f9c89f5-7fba-4600-bb86-951c64d9988e | [email protected] | charlie | sexton | sexton | 
| a27c5ab7-c651-4027-8a89-0eb516930b31 | [email protected]   | charlie | sexton | sexton | 
| f7252552-f54b-453a-9806-2d2e4fd40f43 | [email protected] | charlie | sexton | sexton | 
+--------------------------------------+-------------------------+-----------+----------+----------+ 

代碼用於創建數據....所以在數據庫中的前三項是正確的。所以我做了一次運行下面的代碼來生成前三個記錄。然後得到最後兩條記錄我刪除了session.save(user);然後在第二次運行時更改user2和user3的電子郵件地址。在第二次運行時,我沒有觸及user2或user3的用戶名字段,爲什麼hibernate允許這樣做?我對hibernate相對比較陌生,無法找到資源。 Google God對我不好。

User user = new User(); 
user.setUsername("charles"); 
user.setPassword("sexton"); 
user.setFirstName("charlie"); 
user.setLastName("sexton"); 
user.setEmail("[email protected]"); 

User user2 = new User(); 
user2.setUsername("cs"); 
user2.setPassword("sexton"); 
user2.setFirstName("charlie"); 
user2.setLastName("sexton"); 
user2.setEmail("[email protected]"); 

User user3 = new User(); 
user3.setUsername("cs"); 
user3.setPassword("sexton"); 
user3.setFirstName("charlie"); 
user3.setLastName("sexton"); 
user3.setEmail("[email protected]"); 

SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); 
Session session = sessionFactory.openSession(); 
session.beginTransaction(); 

session.save(user); 
session.save(user2); 
session.save(user3); 

List<Expense> listReport = query.list(); 

session.getTransaction().commit(); 

session.close(); 

回答

1

我想這是因爲你生成UUID的,而不是使一個UUID從您的用戶名

我用我的代碼測試此:

package nl.testing.startingpoint; 

import java.io.IOException; 
import java.util.UUID; 

public class Main { 

    public static void main(String args[]) throws IOException{ 
     String a = "stack Overflow"; 
     String b = "stack Overflow"; 

     System.out.println(UUID.nameUUIDFromBytes(a.getBytes()).toString()); 
     System.out.println(UUID.nameUUIDFromBytes(b.getBytes()).toString()); 

     System.out.println(UUID.nameUUIDFromBytes(a.getBytes()).toString()); 
     System.out.println(UUID.nameUUIDFromBytes(b.getBytes()).toString()); 
    } 
} 

,這是結果:

e6b8789f-8fac-3c40-94ae-6f2fe4b009fc 
e6b8789f-8fac-3c40-94ae-6f2fe4b009fc 
e6b8789f-8fac-3c40-94ae-6f2fe4b009fc 
e6b8789f-8fac-3c40-94ae-6f2fe4b009fc 

但是因爲您使用的註釋與

@GeneratedValue(generator = "uuid") 
@GenericGenerator(name = "uuid", strategy = "uuid2") 

字符串用戶名將被從休眠狀態生成的UUID覆蓋。 相反,我認爲你應該從你傳遞給構造函數的字符串中創建一個UUID。

注:我沒有測試後者,這是一個假設!

+0

我會在稍後測試,但我認爲冬眠會爲我這麼做... – Grim

+0

謝謝你,你的回答是關於..... – Grim