解决这个问题的一种方法是创建一个实现 ResultSetIdentifierConsumer
接口的自定义 UserType。例如,创建一个名为 PostgresIdUUIDType
的类,继承了 PostgresUUIDType
并额外实现了 ParameterizedType
接口进行配置:
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import java.util.TimeZone;
import java.util.UUID;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.id.IdentifierGenerationException;
import org.hibernate.id.ResultSetIdentifierConsumer;
import org.hibernate.type.PostgresUUIDType;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.hibernate.usertype.ParameterizedType;
public class PostgresIdUUIDType
extends PostgresUUIDType
implements ResultSetIdentifierConsumer, ParameterizedType {
private String idColumnName = "id";
@Override
public String getName() {
return "pg-id-uuid";
}
@Override
public void setParameterValues(Properties params) {
idColumnName = params.getProperty("column");
}
@Override
public UUID consumeIdentifier(ResultSet resultSet) throws IdentifierGenerationException {
try {
return nullSafeGet(resultSet, idColumnName, wrapperOptions());
} catch (SQLException e) {
throw new IdentifierGenerationException("Error converting type", e);
}
}
private WrapperOptions wrapperOptions() {
return new WrapperOptions() {
@Override
public boolean useStreamForLobBinding() {
return false;
}
@Override
public LobCreator getLobCreator() {
return null;
}
@Override
public SqlTypeDescriptor remapSqlTypeDescriptor(final SqlTypeDescriptor sqlTypeDescriptor) {
return PostgresUUIDSqlTypeDescriptor.INSTANCE;
}
@Override
public TimeZone getJdbcTimeZone() {
return TimeZone.getDefault();
}
};
}
}
然后在你的实体中定义自定义类型,并像这样将其用于ID列:
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;
@TypeDefs({@TypeDef(name = "pg-id-uuid", typeClass = PostgresIdUUIDType.class) })
@Entity
public class Example {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Type(type="pg-id-uuid", parameters = @Parameter(name = "column", value = "id_column_name"))
private UUID id;
...
}
列@Parameter
使您可以指定不同的数据库列来代替提供的默认id
列。类似于@Column(name = "tag_id")
的工作原理。