Wednesday 27 February 2008

UUID and Hibernate - second update

After testing more scenarios, it appears that the previous solution posted is not complete. Foreign key and compound keys that use a uuid type will fail with what I have documented to date. In order for these to work, you need to take some additional steps.

In the same package as your entity classes containing uuid types, you will need to add a package-info.java class with the following entries:

@org.hibernate.annotations.TypeDefs(
{
@org.hibernate.annotations.TypeDef(
name="uuid",
typeClass = fully.qualified.path.CustomUUIDType.class)
}
)

package fully.qualified.path;

The annotations can also change, but do not need to:


@Id
@GeneratedValue(generator="my_custom_uuid")
@GenericGenerator(name="my_custom_uuid", strategy = "fully.qualified.path.CustomUUIDGenerator")
@Column(name = "id", unique = true, nullable = false, length = 36, columnDefinition="uuid")
@Type(type="uuid")
@NotNull
public String getId() {
return this.id;
}

public void setId(String id) {
this.id= id;
}


Or for a non-@Id field:

@Column(name = "field", unique = true, nullable = false, length = 36, columnDefinition="uuid")
@Type(type="uuid")
@NotNull
public String getFieldValue() {
return this.fieldValue;
}

public void setFieldValue(String fieldValue) {
this.fieldValue = fieldValue;
}


Additionally, you will also need to override the PostgreSQLDialect.java class with the following:

import java.sql.Types;

//This is to address the mapping exception when using uuid data type in PostgreSQL with Hibernate
//javax.persistence.PersistenceException: org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111
//This makes the assumption that no other fields types will be using the java.sql.Types.OTHER data type
public class CustomUUIDPostgreSQLDialect extends org.hibernate.dialect.PostgreSQLDialect {

public CustomUUIDPostgreSQLDialect() {
super();
registerColumnType(Types.OTHER, "uuid");
registerHibernateType(Types.OTHER, "string");
}

}

Having done that, you will then need to update the persistence.xml file in your META-INF directory changing the following property:

<property name="hibernate.dialect" value="fully.qualified.path.CustomUUIDPostgreSQLDialect"/>

So for me at least, this is what I needed to do to get the postgreSQL uuid data type to work with Hibernate. If you are attempting to do the same, hopefully your journey will not be too different from what I have documented, and you will have smoother sailing than I have had.

1 comment:

Unknown said...

Andrew,
Do you have your complete example solution available anywhere?
Thanks,
-David