web-dev-qa-db-ja.com

JPA / hibernateでのUUIDのマッピングに関する問題

ドキュメントによると、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で何も見つけることができませんでした:)

ありがとう

28
Piotr

UUIDは3.6で追加された基本タイプです。ただし、デフォルトでは、mysqlに問題を引き起こすように見えるJDBC Binaryタイプに変換されます。タイプとしてuuid-charを明示的に指定することで、この動作をオーバーライドできます。

27
Mike Lively

Mike Livelyの回答をコードサンプルで拡張し、Oracleを参照する。

OracleDialect(Oracle10gDialect)でこの問題が発生しました。注釈@TypeをUUIDフィールドに追加すると修正されました。

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

注:@FieldBridgeアノテーションを使用して、このフィールドでTwoWayStringBridgeも使用しました。

注:type = "uuid-binary"は機能しませんでした。同じ不明なタイプのエラーが発生しました。

37
Barett
Caused by: org.hibernate.MappingException: No Dialect mapping for JDBC type: -2

つまり、UUIDはHibernateによってBINARY [1]としてマップされますが、MySQLダイアレクトは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

これはmayHibernateのバグである可能性があります。MySQLのドキュメントでBINARYデータ型が利用可能であることはわかりますが、Hibernateの検索を実行したい場合があります。 JIRAを使用して、これがマップされない理由があるかどうかを確認してください。

テストしたい場合は、MySQL5InnoDBDialectをサブクラス化し(InnoDBを使用している場合)、これをコンストラクターに使用できます。

registerColumnType( Types.BINARY, "binary" );

したがって、これがStringが機能している理由ですが、Java.util.UUIDは機能していません。

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

9
jpkrohling

InnoDBテーブルでHibernate 4とMySQL 5.5を使用して、UUIDカラムをBINARY(16) as-isとして保存できました(構成やカスタムタイプは必要ありません)。これをエンティティIDとして使用せず、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                |
| ...            |               |      |     |                     |
+----------------+---------------+------+-----+---------------------+
7
David Harkness

タイプUUIDは使用しないでください。これを処理するにはカスタムタイプが必要です。

Stringを使用します。 この投稿 を参照してください。それを実装する方法の1つです。

もう1つの方法は、Hibernateに組み込まれているUUIDジェネレーターを使用することです。 @GeneratedValueという名前のジェネレーターとhibernate-uuidが必要です。

3
Bozho

JDBCを使用したUUIDマッピングを探していたときに、Google検索でこの投稿につながったので、よろしければ私の経験を投稿します。

私のプロジェクトでは、ユニットテストでH2を使用してH2とMySqlを切り替えています。 H2はUUIDタイプをネイティブにサポートします。しかし、mysql Javaコネクタはサポートしていません。そのため、私の唯一のオプションは、私が気に入らないクライアントコードでBINARY(16)UUIDに変換することです。

その結果、公式のmysql Javaコネクターにパッチを当てて、UUIDをBINARY(16)として扱うようにしました。これはちょっとハッキーですが、私にとってはうまくいきます。

試してみたい場合は、githubに投稿します。 http://goo.gl/NIhNi

0
expert