我们使用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
我想知道是否有更好的方法来处理这件事。还是我在实现中遗漏了什么?
2条答案
按热度按时间tkqqtvp11#
为什么使用native query?使用JPQL/HQL查询:
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