Hibernate 6.1:从PostgreSQL阅读UUID

zd287kbt  于 2023-04-12  发布在  PostgreSQL
关注(0)|答案(1)|浏览(204)

我正在从Sping 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);
}

在Sping Boot 2/Hibernate 5中,UUID正确返回为0f787085-9a45-4512-ae55-f6db24ab8178mostSigBits = 1114764626895389970leastSigBits = -5884525917016194696)。
但是在升级到Sping Boot 3/Hibernate 6之后,UUID返回为30663738-3730-3835-2d39-6134352d3435mostSigBits = 3487535676028631093mostSigBits = 3487535676028631093)-我真的不知道为什么或者该怎么办。
我使用完全相同的运行配置,只是切换Git分支并重建所有内容。
我已经尝试将hibernate.type.preferred_uuid_jdbc_type设置为CHARBINARY,但返回的值是相同的。PostgreSQL驱动程序版本是42.5.4。
这是一个Hibernate bug吗?我还能做些什么来解决这个问题?

m2xkgtsf

m2xkgtsf1#

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

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)
    )

我相信这和你的模式是一样的
然后插入一行,让Postgres生成UUID:

insert 
    into It
        default values
    returning uuid

它最后Assertdb的字符串表示和Java的字符串表示是相同的(当然,我还在命令行上仔细检查了psql)。
在我看来这里的一切都很完美。
我不知道你的情况怎么样了。

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

相关问题