I am using Oracle database and have to define a UUID column. I followed other posts and created the table using regex pattern for primary key:
CREATE TABLE TEST_UUID (
ID_UUID VARCHAR(255)
DEFAULT REGEXP_REPLACE(RAWTOHEX(SYS_GUID()), '([A-F0-9]{8})([A-F0-9]{4})([A-F0-9]{4})([A-F0-9]{4})([A-F0-9]{12})', '\1-\2-\3-\4-\5'),
NAME VARCHAR2(40) NOT NULL
);
In my entity class I have to define the ID_UUID column of type UUID (cannot define it as String). The entity class looks like this:
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "test_uuid")
public class TestUuid {
@Id
@Column(name = "id_uuid")
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID idUuid;
@Column(name = "name")
private String name;
/**
* @return the idUuid
*/
public UUID getIdUuid() {
return idUuid;
}
/**
* @param idUuid the idUuid to set
*/
public void setIdUuid(UUID idUuid) {
this.idUuid = idUuid;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
}
When I retrieve the table values I don't get the same value for ID_UUID whats stored in the database because of UUID data type (if I change it to a String I am able to pull the correct value). My limitation is to use the UUID type as I am migrating from Postgre to Oracle database and cannot change my entity class. Is it possible to retrieve the correct value using UUID data type?
CodePudding user response:
You need to define custom type that stores and retrieves UUID type as VARCHAR.
See Hibernate UUID type implementation.
https://github.com/hibernate/hibernate-orm/blob/main/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/UUIDJavaType.java
In case if you have Hibernate 5 or higher you can use it.
- Create own user type
public class UUIDType extends AbstractSingleColumnStandardBasicType<UUID> {
public static final UUIDType INSTANCE = new UUIDType();
public static final String NAME = "UUIDType";
public UUIDType() {
super(VarcharTypeDescriptor.INSTANCE, UUIDTypeDescriptor.INSTANCE);
}
@Override
public String getName() {
return NAME;
}
}
- Implement a
UUIDTypeDescriptor
for storing and retrieving UUID as VARCHAR
public class UUIDTypeDescriptor extends AbstractTypeDescriptor<UUID> {
public static final UUIDTypeDescriptor INSTANCE = new UUIDTypeDescriptor();
public UUIDTypeDescriptor() {
super(UUID.class, ImmutableMutabilityPlan.INSTANCE);
}
@Override
public String toString(UUID uuid) {
return uuid.toString();
}
@Override
public UUID fromString(String s) {
return UUID.fromString(s);
}
@Override
public <T> T unwrap(UUID uuid, Class<T> type, WrapperOptions wrapperOptions) {
if (uuid == null) return null;
if (String.class.isAssignableFrom(type)) {
return (T) uuid.toString();
}
throw unknownUnwrap(type);
}
@Override
public <T> UUID wrap(T value, WrapperOptions wrapperOptions) {
if (value == null)
return null;
if(value instanceof String) {
return UUID.fromString((String) value);
}
throw unknownWrap(value.getClass());
}
}
- Apply custom type to your entity
Specific for entity:
@TypeDef(name = UUIDType.NAME,
typeClass = UUIDType.class,
defaultForType = UUID.class)
@Entity
@Table(name = "test_uuid")
public class TestUUID {
}
or on package lavel in package-info.java
file:
@TypeDef(
name = UUIDType.NAME,
typeClass = UUIDType.class,
defaultForType = UUID.class
)
package com.model;