Problems mapping UUID in JPA/hibernate

杀马特。学长 韩版系。学妹 提交于 2019-11-28 08:08:11

UUID was a basic type added in 3.6. However, by default it translates to a JDBC Binary type which appears to cause issues for mysql. You can override this behavior by explicitly specifying uuid-char as the type.

Extending Mike Lively's answer with a code sample & referring to Oracle too.

I had this problem with the OracleDialect (Oracle10gDialect). Adding an annotation @Type to the UUID field fixed it for me.

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

Note: also used a TwoWayStringBridge on this field, using the @FieldBridge annotation.

Note: type="uuid-binary" did not work; got the same, unknown type error.

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

This means that UUID is being mapped as BINARY[1] by Hibernate, but none MySQL Dialects maps BINARY to a MySQL data type. Take a look at the Dialect hierarchy for 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

Compare them with this one (search for the BINARY mapping): https://github.com/hibernate/hibernate-core/blob/master/hibernate-core/src/main/java/org/hibernate/dialect/HSQLDialect.java

This may be a bug in Hibernate, as I do see the BINARY data type available in the MySQL documentation, but you may want to do some search in Hibernate's JIRA to see if there's any reason why this is not mapped.

If you are willing to test, you can just subclass MySQL5InnoDBDialect (if you are using InnoDB), and use this to the constructor:

registerColumnType( Types.BINARY, "binary" );

So, this is the reason why the String is working, but java.util.UUID is not.

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

Using Hibernate 4 and MySQL 5.5 with an InnoDB table, I was able to store a UUID column as BINARY(16) as-is (no configuration or custom type required). I am not using this as the entity ID and am creating the value manually using 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                |
| ...            |               |      |     |                     |
+----------------+---------------+------+-----+---------------------+

Don't use the type UUID, because you'd need a custom type to handle it.

Use String. See this post. It is one way of implementing it.

Another way is to use the UUID generator built in hibernate. You'd need @GeneratedValue with a generator named hibernate-uuid

Google search led me to this post when I was looking for UUID mapping with JDBC so I'll post my experience if you don't mind.

On my project I'm switching between H2 and MySql using H2 in unit-testing. H2 natively supports UUID type. But mysql java connector doesn't. So my only option is to convert BINARY(16) to UUID in client code which I don't like.

As result I patched official mysql java connector to treat UUID as BINARY(16). I know it's kinda hacky but works for me.

If you want to try it I posted it on github: http://goo.gl/NIhNi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!