Hibernate 6.1: reading UUID from PostgreSQL



我正在从Spring Boot 2升级到3,同时也从Hibernate 5升级到6.1。

我有一个包含UUID列的PostgreSQL表:

Table "public.combination"
Column           |   Type    | Collation | Nullable |      Default      
----------------------------+-----------+-----------+----------+-------------------
id                         | uuid      |           | not null | gen_random_uuid()
kind                       | kind_type |           | not null | 

我有一个带有该列的JPA模型:

import java.util.UUID;
@Entity
@Table(name = "combination")
public class Combination
{
@Id
@Column(name = "id")
@NotNull
private UUID id;
public UUID getId()
{
return id;
}
...

表中的一条记录:

argas=# select * from combination ;
id                  |    kind     
--------------------------------------+---------------
0f787085-9a45-4512-ae55-f6db24ab8178 | connectivity
(1 rows)

我使用CrudRepository子类从表中查询:

@Repository
public interface CombinationRepository extends CrudRepository<Combination, UUID>
{
Iterable<Combination> findAllByKind(@NotNull Kind kind);
}

在Spring Boot 2/Hibernate 5中,UUID正确返回为0f787085-9a45-4512-ae55-f6db24ab8178(mostSigBits = 1114764626895389970,leastSigBits = -5884525917016194696)。

但是在升级到Spring Boot 3/Hibernate 6之后,UUID返回为30663738-3730-3835-2d39-6134352d3435(mostSigBits = 3487535676028631093,mostSigBits = 3487535676028631093) -我真的不知道为什么或如何处理它。

我使用完全相同的运行配置,只是切换Git分支并重新构建所有内容。

我已经尝试将hibernate.type.preferred_uuid_jdbc_type设置为CHARBINARY,但返回的值是相同的。PostgreSQL驱动版本为42.5.4.

这是Hibernate的bug吗?我还能做些什么来解决这个问题?

为了重现这种行为,我编写了这个测试:

package org.hibernate;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.Generated;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.UUID;
@SessionFactory
@DomainModel(annotatedClasses = UuidTest.It.class)
public class UuidTest {
@Test
void testit(SessionFactoryScope scope) {
scope.inTransaction( s -> s.persist( new It() ) );
scope.inTransaction( s -> {
UUID uuid = s.createQuery("select uuid from It", UUID.class).getSingleResult();
String string = s.createQuery("select str(uuid) from It", String.class).getSingleResult();
Assertions.assertEquals( string, uuid.toString() );
System.out.println( string );
});
}
@Entity(name="It")
public static class It {
@Id @Generated
@ColumnDefault("gen_random_uuid()")
UUID uuid;
}
}

生成以下DDL:

create table It (
uuid uuid default gen_random_uuid() not null,
primary key (uuid)
)

我相信它和你的schema是一样的。

然后插入一行,让Postgres生成UUID:

insert 
into It
default values
returning uuid

它最后断言db的字符串表示和Java的字符串表示是相同的。(当然,我也在命令行中仔细检查了psql。)

在我看来这里的一切都很完美。

我不知道你是怎么回事。

更新:我的观点是,它看起来不像Hibernate中的一个bug。当然,我不知道Spring在这一切中做了什么。

最新更新