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

Hibernate is generating duplicate primary keys while using uuid

我遇到了休眠多次存储相同密钥的问题。例如,假设我有一个主键为 "stack overflow" 的对象。我创建了另一个具有相同主键 "stack overflow" 的对象,hibernate 将保存这两个对象并且每个对象都有自己的记录。我个人认为这是由 uuid 引起的,因为 "stack overflow" 不会在数据库中出现两次,但每个对象的唯一 uuid 是不同的。如何修复为字符串生成不同的 uuid?

用户 class,电子邮件字段按预期工作,不允许重复的电子邮件。

@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

Table数据

+--------------------------------------+-------------------------+-----------+----------+----------+
| 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 允许这样做?我对休眠比较陌生,找不到资源。 Google 上帝对我不好。

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();

我认为这是因为您生成了 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。

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