dubdubdubdot dubdubdubdot - 4 months ago 37
Java Question

Using Different Hibernate User Types in Different Situations

I am using Hibernate + JPA as my ORM solution.

I am using HSQL for unit testing and PostgreSQL as the real database.

I want to be able to use Postgres's native UUID type with Hibernate, and use the UUID in its String representation with HSQL for unit testing (since HSQL does not have a UUID type).

I am using a persistence XML with different configurations for Postgres and HSQL Unit Testing.

Here is how I have Hibernate "see" my custom UserType:

@Id
@Column(name="UUID", length=36)
@org.hibernate.annotations.Type(type="com.xxx.UUIDStringType")
public UUID getUUID() {
return uuid;
}


public void setUUID(UUID uuid) {
this.uuid = uuid;
}


and that works great. But what I need is the ability to swap out the "com.xxx.UUIDStringType" part of the annotation in XML or from a properties file that can be changed without re-compiling.

Any ideas?

Answer

This question is really old and has been answered for a long time, but I recently found myself in this same situation and found a good solution. For starters, I discovered that Hibernate has three different built-in UUID type implementations:

  1. binary-uuid : stores the UUID as binary
  2. uuid-char : stores the UUID as a character sequence
  3. pg-uuid : uses the native Postgres UUID type

These types are registered by default and can be specified for a given field with a @Type annotation, e.g.

@Column
@Type(type = "pg-uuid")
private UUID myUuidField;

There's also a mechanism for overriding default types in the Dialect. So if the final deployment is to talk to a Postgres database, but we the unit tests use HSQL, you can override the pg-uuid type to read/write character data by writing a custom dialect like so:

public class CustomHSQLDialect extends HSQLDialect {

    public CustomHSQLDialect() {
        super();

        // overrides the default implementation of "pg-uuid" to replace it
        // with varchar-based storage.
        addTypeOverride(new UUIDCharType() {
            @Override
            public String getName() {
                return "pg-uuid";
            }
        });
    }
}

Now just plug in the custom dialect, and the the pg-uuid type is available in both environments.

Comments