Hibernate не может вставить UUID в столбец VARCHAR

#java #mysql #hibernate #playframework

#java #mysql #спящий режим #playframework

Вопрос:

Я работаю над настройкой базы данных MySQL и использованием Hibernate и Play Framework для серверной части. У меня возникли проблемы с идентификаторами записей. Я определил свой столбец id как VARCHAR(36) :

 CREATE TABLE `logaritmical`.`users` (
   `id` VARCHAR(36) NOT NULL,
   `username` TEXT NOT NULL,
    `email` TEXT NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE INDEX `id_UNIQUE` (`id` ASC)
);
 

Теперь @Entity класс выглядит следующим образом:

 @Entity
@Table(name = "users")
public class UserDO {

   @Id
   @GeneratedValue(generator = "uuid2")
   @GenericGenerator(name = "uuid2", strategy = "uuid2")
   @Column(name = "id", updatable = false, nullable = false, columnDefinition = "VARCHAR(36)")
   private UUID id;
    
   @Column
   private String username;
    
   @Column
   private String email;
}
 

При выполнении вставки я получаю следующую ошибку: Incorrect string value: 'xEFxA5!x89xF3K...' for column 'id' at row 1

Если я изменю тип столбца и ColumnDefinition на BINARY(16) insert, это сработает, но у него есть тот недостаток, что идентификатор не читается человеком при выполнении выбора.

Дополнительная информация: persistence.xml выглядит так:

 <persistence-unit name="defaultPersistenceUnit" transaction-type="RESOURCE_LOCAL">
   <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
   <non-jta-data-source>DefaultDS</non-jta-data-source>
   <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/>
   </properties>
</persistence-unit>
 

Конфигурация БД и версии библиотек выглядят следующим образом:
jpa.default=defaultPersistenceUnit
"org.hibernate" % "hibernate-entitymanager" % "5.4.24.Final",
"mysql" % "mysql-connector-java" % "8.0.22",

Что можно сделать , чтобы иметь UUID возможность работать с VARCHAR ? Есть ли что-то, чего мне не хватает?

Комментарии:

1. Какой диалект гибернации вы используете?

2. Я использую MySQL8Dialect. Редактирование, чтобы добавить эту информацию, хорошо.

Ответ №1:

Попробуйте использовать следующее определение:

 import org.hibernate.annotations.Type;

@Entity
@Table(name = "users")
public class UserDO {
    @Id
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "uuid2")
    @Column(name = "id", updatable = false, nullable = false, columnDefinition = "VARCHAR(36)")
    @Type(type = "uuid-char")
    private UUID id;

    // ...
}
 

Похоже, что для вашего диалекта UUID по умолчанию отображается uuid-binary базовый тип.

PS Пожалуйста, обратите внимание, что сохранение UUID PK в виде строки может привести к проблемам с производительностью, как это объясняется в этой статье:

Помимо 9-кратной стоимости по размеру (36 против 4 байт для int), строки сортируются не так быстро, как числа, потому что они зависят от правил сортировки.

Комментарии:

1. Я только что увидел более позднюю правку об использовании UUID в качестве PK. Действительно открыл мне глаза! Обязательно пересмотрю это.