Hibernate генерирует дубликаты первичных ключей при использовании uuid

У меня проблема, когда спящий режим хранит одни и те же ключи несколько раз. Например, скажем, у меня есть объект с первичным ключом как «переполнение стека». Я создаю другой объект с тем же первичным ключом «переполнение стека», hibernate сохранит оба объекта, и каждый объект будет иметь свою собственную запись. Я лично считаю, что это вызвано uuid, поскольку «переполнение стека» не будет отображаться в базе данных дважды, но уникальный uuid каждого объекта отличается. Как исправить создание другого uuid для строк?

Users, поле электронной почты работает должным образом и не позволяет дублировать электронные письма.

@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 при втором запуске, почему спящий режим разрешает это? Я относительно новичок в спящем режиме и не смог найти ресурсы. Бог Google не был добр ко мне.

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

person Grim    schedule 09.06.2016    source источник


Ответы (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 из строки, которую вы передаете в конструктор.

ПРИМЕЧАНИЕ. Последнее я не проверял, это предположение!

person Igoranze    schedule 09.06.2016
comment
Я проверю это позже, но я думал, что спящий режим в значительной степени сделает это для меня.... - person Grim; 09.06.2016