Проблемы с отображением UUID в JPA / hibernate - PullRequest
26 голосов
/ 03 декабря 2010

Согласно документации, hibernate 3.6 должен иметь поддержку типа java.util.UUID.Но когда я отображаю это как:

@Id protected UUID uuid;

, я получаю следующее исключение:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [test-applicationContext.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: persistenceUnit] Unable to build EntityManagerFactory
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420) ~[spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) ~[spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) ~[spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291) ~[spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288) ~[spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) ~[spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findDefaultEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:529) ~[spring-orm-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:495) ~[spring-orm-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.java:656) ~[spring-orm-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.getResourceToInject(PersistenceAnnotationBeanPostProcessor.java:629) ~[spring-orm-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:147) ~[spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84) ~[spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:338) ~[spring-orm-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    ... 51 common frames omitted
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: persistenceUnit] Unable to build EntityManagerFactory
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:911) ~[hibernate-entitymanager-3.6.0.Final.jar:3.6.0.Final]
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:74) ~[hibernate-entitymanager-3.6.0.Final.jar:3.6.0.Final]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:225) ~[spring-orm-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:308) ~[spring-orm-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477) ~[spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417) ~[spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    ... 64 common frames omitted
Caused by: org.hibernate.MappingException: No Dialect mapping for JDBC type: -2
    at org.hibernate.dialect.TypeNames.get(TypeNames.java:78) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]
    at org.hibernate.dialect.TypeNames.get(TypeNames.java:103) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]
    at org.hibernate.dialect.Dialect.getTypeName(Dialect.java:249) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]
    at org.hibernate.mapping.Column.getSqlType(Column.java:208) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]
    at org.hibernate.mapping.Table.sqlTemporaryTableCreateString(Table.java:371) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]
    at org.hibernate.mapping.PersistentClass.prepareTemporaryTables(PersistentClass.java:765) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]
    at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:270) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1842) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:902) ~[hibernate-entitymanager-3.6.0.Final.jar:3.6.0.Final]
    ... 69 common frames omitted

Я знаю, что вопросы со трассировкой стека не очень популярны, но это очень специфичная для спящего режима проблемаи я не смог найти что-либо на Google:)

Спасибо

Ответы [ 6 ]

36 голосов
/ 28 января 2011

Расширение ответа Майка Лайвли с примером кода и ссылкой на Oracle.

У меня была эта проблема с OracleDialect (Oracle10gDialect).Добавление аннотации @Type к полю UUID исправило это для меня.

@Id
@Type(type="uuid-char")
private UUID id;

Примечание: также использовал TwoWayStringBridge для этого поля, используя аннотацию @FieldBridge.

Примечание: type = "uuid-binary "не работает;получил ту же, неизвестную ошибку типа.

27 голосов
/ 03 декабря 2010

UUID был базовым типом, добавленным в 3.6.Однако по умолчанию он преобразуется в двоичный тип JDBC, который, по-видимому, вызывает проблемы для mysql.Вы можете переопределить это поведение, явно указав uuid-char в качестве типа.

9 голосов
/ 03 декабря 2010
Caused by: org.hibernate.MappingException: No Dialect mapping for JDBC type: -2

Это означает, что UUID отображается как BINARY [1] в Hibernate, но ни один из MySQL Dialects не отображает BINARY в тип данных MySQL.Посмотрите на иерархию диалектов для MySQL:

https://github.com/hibernate/hibernate-core/blob/master/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java

https://github.com/hibernate/hibernate-core/blob/master/hibernate-core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java

https://github.com/hibernate/hibernate-core/blob/master/hibernate-core/src/main/java/org/hibernate/dialect/MySQL5InnoDBDialect.java

Сравните их с этим (поискдля отображения BINARY): https://github.com/hibernate/hibernate-core/blob/master/hibernate-core/src/main/java/org/hibernate/dialect/HSQLDialect.java

Этот может быть ошибкой в ​​Hibernate, так как я вижу тип данных BINARY, доступный в документации MySQL, но вы можете сделать некоторыевыполните поиск в JIRA Hibernate, чтобы выяснить, есть ли какая-либо причина, по которой это не отображается.

Если вы хотите выполнить тестирование, вы можете просто создать подкласс MySQL5InnoDBDialect (если вы используете InnoDB) и использовать его для конструктора:

registerColumnType( Types.BINARY, "binary" );

Итак, по этой причине работает строка, а java.util.UUID - нет.

1 - http://download.oracle.com/javase/6/docs/api/constant-values.html#java.sql.Types.BINARY

7 голосов
/ 14 января 2013

Используя Hibernate 4 и MySQL 5.5 с таблицей InnoDB, я смог сохранить столбец UUID как BINARY(16) как есть (конфигурация или пользовательский тип не требуются).Я не использую это как идентификатор объекта и создаю значение вручную, используя UUID.randomUUID().

@Entity
@Table(name = "post")
public class PostModel implements Serializable
{
    ...
    @Column(name = "uuid", nullable = false, updatable = false)
    private UUID uuid;
    ...
}

> desc post;
+----------------+---------------+------+-----+---------------------+
| Field          | Type          | Null | Key | Default             |
+----------------+---------------+------+-----+---------------------+
| ...            |               |      |     |                     |
| uuid           | binary(16)    | YES  | UNI | NULL                |
| ...            |               |      |     |                     |
+----------------+---------------+------+-----+---------------------+
3 голосов
/ 03 декабря 2010

Не используйте тип UUID, потому что вам понадобится пользовательский тип для его обработки.

Использование String.Смотрите этот пост .Это один из способов его реализации.

Другой способ - использовать генератор UUID, встроенный в спящий режим.Вам понадобится @GeneratedValue с генератором с именем hibernate-uuid

0 голосов
/ 07 июня 2013

Поиск в Google привел меня к этому сообщению, когда я искал UUID-отображение в JDBC, поэтому я опубликую свой опыт, если вы не возражаете.

В моем проекте я переключаюсь между H2 и MySqlиспользуя H2 в модульном тестировании.H2 изначально поддерживает тип UUID.Но MySQL Java-соединитель не делает.Поэтому мой единственный вариант - конвертировать BINARY(16) в UUID в коде клиента, который мне не нравится.

В результате я установил официальный Java-коннектор mysql для обработки UUID как BINARY (16).Я знаю, что это немного странно, но у меня работает.

Если вы хотите попробовать, я разместил это на github: http://goo.gl/NIhNi

...