有没有一种方法可以让Hibernate在查询时将UNIQUEIDENTIFIER类型数据转换为String for H2 DB?

x7rlezfr  于 2023-10-23  发布在  其他
关注(0)|答案(2)|浏览(116)

我们使用H2 DB进行集成测试/本地开发,使用Azure SQL Server进行阶段环境。有些情况下,一个查询在SQL Server上工作正常,但在H2 DB上不工作,反之亦然。
其中一个例子是在SQL Server中对UUID类型列使用GUID标识符数据类型时。JPA/Hibernate与Java. util. UUID数据类型兼容,并与Java.util.UUID类型Map良好。在保存时,UUID将以UUID格式正确存储。在获取(选择查询)时,UUID作为字符串返回,可以使用UUID.fromString()API将其转换为UUID。
但H2 DB并非如此。Hibernate自动为Java.util.UUID属性创建类型为Binary(255)的列。在保存时,UUID被存储为非UUID格式(十六进制格式)。在fetch(选择查询)时,它以Byte[]的形式出现。
因此,当您试图将查询resultSet转换为Java对象时,代码会中断。
我们尝试在Entity中的UUID类型属性上使用@Column(columnDefinition =“Columneidentifier”)注解。通过此更改,现在列的数据类型更改为DataIdentifier。然而,在fetch时,Hibernate仍然将其转换为Byte[]。
实体:

@ToString
@Table(name="TASK")
public class Task {
    @Id
    @Column(columnDefinition = "UNIQUEIDENTIFIER")
    private UUID id;
    private String name;
}

查询和转换:

Query query = entityManager.createNativeQuery("SELECT id, name from task where id=?");
        query.setParameter(1,id);
        List<Object[]> resultList = query.getResultList();
        Task task = null;
        for (Object[] row: resultList) {
            Integer rowIndex =0;
                                                    /***Code fails here***/
            task = Task.builder().id(UUID.fromString((String) row[rowIndex])).name((String) row[rowIndex+1]).build();
        }

其他细节:

H2 version: 1.4.200
Hibernate version: 5.4.28.Final

我想知道是否有更好的方法来处理这件事。还是我在实现中遗漏了什么?

tkqqtvp1

tkqqtvp11#

为什么使用native query?使用JPQL/HQL查询:

TypedQuery<Task> query = entityManager.createQuery("SELECT t from Task 
 t where t.id=?", Task.class);
query.setParameter(1, id);
List<Task> tasks = query.getResultList();
l2osamch

l2osamch2#

我们需要使用h2 db url的兼容模式,如下所示:
1.要使用MS SQL Server模式,请使用数据库URL jdbc:h2:~/test;=MSSQLServer; DATA_TO_UPPER= 0; CASE_INSENSITIVE_IDENTIFIERS=TRUE。创建后,不要更改DATABASE_TO_LOWER和CASE_INSENSITIVE_IDENTIFIERS的值
1.要使用IBM DB2模式,请使用数据库URL jdbc:h2:~/test; MODE=DB2;DEFAULT_NULL_ORDERING=HIGH或SQL语句SET MODE DB2。
更多详情https://www.h2database.com/html/features.html#compatibility

相关问题