Hibernate在使用uuid时生成重复的主键

时间:2016-06-09 12:52:41

标签: hibernate uuid

我遇到的问题是hibernate多次存储相同的密钥。例如,假设我有一个带有主键的对象为"堆栈溢出"。我使用相同的主键创建另一个对象"堆栈溢出",hibernate将保存两个对象,每个对象都有自己的记录。我个人认为这是由于uuid因为堆栈溢出而造成的#34;不会两次出现在数据库中,但每个对象的唯一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 | -----@yahoo.com         | charlie   | sexton   | sexton   |
| 365a64b0-e036-4654-ad3a-afe2440f5b37 | ton@yahoo.com           | charlie   | sexton   | sexton   |
| 9f9c89f5-7fba-4600-bb86-951c64d9988e | seeeexxxxxxon@yahoo.com | charlie   | sexton   | sexton   |
| a27c5ab7-c651-4027-8a89-0eb516930b31 | sexon@yahoo.com         | charlie   | sexton   | sexton   |
| f7252552-f54b-453a-9806-2d2e4fd40f43 | ----------@yahoo.com    | charlie   | sexton   | sexton   |
+--------------------------------------+-------------------------+-----------+----------+----------+

用于创建数据的代码....因此数据库中的前三个条目是正确的。所以我所做的是运行以下代码一次以生成前三个记录。然后,为了得到最后两条记录,我删除了session.save(user);然后在第二次运行时更改了user2和user3的电子邮件地址。我没有在第二次运行时触摸user2或user3的用户名字段,为什么hibernate允许这样做?我对休眠相对较新,无法找到资源。谷歌上帝对我不好。

User user = new User();
user.setUsername("charles");
user.setPassword("sexton");
user.setFirstName("charlie");
user.setLastName("sexton");
user.setEmail("ton@yahoo.com");

User user2 = new User();
user2.setUsername("cs");
user2.setPassword("sexton");
user2.setFirstName("charlie");
user2.setLastName("sexton");
user2.setEmail("sexon@yahoo.com");

User user3 = new User();
user3.setUsername("cs");
user3.setPassword("sexton");
user3.setFirstName("charlie");
user3.setLastName("sexton");
user3.setEmail("-----@yahoo.com");

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 个答案:

答案 0 :(得分: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")

使用来自hibernate的生成的UUID覆盖String用户名。 相反,我认为你应该从你传递给构造函数的字符串中创建一个UUID。

注意:我没有测试后者,这是一个假设!