Reputation: 1613
Upgrading one of our framework libraries caused our version of Hibernate to upgrade from 4 to 5. In doing so, now our queries to our PostgreSQL database are failing with the following exception.
Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: bytea = uuid Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Position: 1827
The problem seems to be converting from bytea to a Java UUID. All of our record id's are Java UUID's written to bytea to the database as was the norm in Hibernate 4. Below is the JPA annotations used to define the id field. We had no issues with this in Hibernate 4 and I suspect that I need to changes my annotations to get it to work again in Hibernate 5
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
private UUID id;
I noticed that a change added to org.hibernate.type.PostgresUUIDType was the addition of the method:
@Override
protected boolean registerUnderJavaType() {
// register this type under UUID when it is added to the basic type registry
return true;
}
which i presume defaults the handling of Java UUID's to the PostgreSQL's native UUID type. This change was make specifically in Hibernate 5 (https://hibernate.atlassian.net/browse/HHH-9577)
My question is how do i get back Hibernate 4 behavior back as we already have an existing database schema in place.
Thank you.
UPDATE
I found the migration guide documented here: https://github.com/hibernate/hibernate-orm/blob/5.0/migration-guide.adoc
it states the following:
For ids defined as UUID with generation, for some databases it is required to explicitly set the @Column( length=16 ) in order to generate BINARY(16) so that comparisons properly work.
I tried this and still no change in behavior.
Upvotes: 3
Views: 3821
Reputation: 382
In case you have a lot of UUID attributes as I did, you could use a @TypeDef
annotation at the package level (in a package-info.java
file), as:
// Forces UUID attributes to be mapped as binary columns (for backward-compatibility)
@TypeDef(defaultForType = UUID.class, typeClass = UUIDBinaryType.class)
package <your top-level package>;
import org.hibernate.annotations.TypeDef;
import org.hibernate.type.UUIDBinaryType;
import java.util.UUID;
It's not the cleanest solution, but it avoids having to change each and every UUID attribute.
Upvotes: 2
Reputation: 1613
I believe I found the solution. I needed to now mark my UUID types with type "uuid-binary". Verified that this generates they type as bytea in Postgres and that i can read records from my existing database.
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Type(type = "uuid-binary")
private UUID id;
Upvotes: 1