我正在从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
设置为CHAR
或BINARY
,但返回的值是相同的。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在这一切中做了什么。