我正在构建一个Spring Boot应用程序,它根据以下属性自动配置我的JPA数据源。
spring.datasource.url=jdbc:jtds:sqlserver://localhost;DatabaseName=testDB;useCursors=true
spring.datasource.username=testDBUser
spring.datasource.password=test123
spring.datasource.driver-class-name=net.sourceforge.jtds.jdbc.Driver
spring.datasource.maxActive=100
spring.datasource.minIdle=5
spring.datasource.removeAbandoned=true
spring.datasource.removeAbandonedTimeout=300
spring.datasource.defaultTransactionIsolation=REPEATABLE_READ
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServer2008Dialect
spring.jpa.properties.hibernate.show_sql=false
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.use_query_cache=true
现在,我有一个表格如下
TableA{
String id;
String prop1;
String prop2;
String prop3;
}
失败的测试用例如下。正如您在下面看到的,我只是想比较EntityManager与Spring Data Repository的结果。
测试失败,因为从EntityManager返回的“id”值是“D97”(大写),而从Spring Data存储库返回的值是“d97”。实际值是“d97”。
@Test
public void testIfSpringRepositoryWorks() {
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
List<TableAEntity> result = entityManager.createQuery("FROM TableAEntity WHERE id='d97'" , TableAEntity.class).getResultList();
if(result==null) {
Assert.fail("Empty Result from EntityManager for id: d97 ");
} else {
TableAEntity fromEntityManager = result.get(0);
TableAEntity fromSpringJPA = tableARepository.findOne("d97");
if(!fromEntityManager.equals(fromSpringJPA)) {
Assert.fail("TableAEntity is not same");
}
}
entityManager.getTransaction().commit();
entityManager.close();
}
我不确定为什么EntityManager将我的id字段转换为大写字母。请帮助找出根本原因。
谢谢!
答案 0 :(得分:1)
我不确定这是一个问题还是我创造一个解决方案的情况。但这是正在发生的事情。
在上面的测试中,我对Spring JPA的查询是
tableARepository.findOne("d97");
相当于
entityManager.find(TableA.class,"d97");
当执行两者中的任何一个时,代码的下面部分在Hibernate Row Reader逻辑中形成实体键(org.hibernate.loader.plan.exec.process.internal.RowSetProcessorHelper)。
public static EntityKey getOptionalObjectKey(QueryParameters queryParameters, SessionImplementor session) {
final Object optionalObject = queryParameters.getOptionalObject();
final Serializable optionalId = queryParameters.getOptionalId();
final String optionalEntityName = queryParameters.getOptionalEntityName();
return INSTANCE.interpretEntityKey( session, optionalEntityName, optionalId, optionalObject );
}
不用说,作为键传递的任何参数理想情况下都是返回对象的主键值(忽略数据库返回的值)。
现在,当我执行查询
时 List<TableAEntity> result = entityManager.createQuery("FROM TableAEntity WHERE id='d97'" , TableAEntity.class).getResultList()
由于我没有直接将任何主键传递给hibernate,它可能只保留了hibernate返回的值。
现在,由于SQLServer默认排序规则不区分大小写,因此在返回数据时它会将我的主键大写。
我不确定为什么Hibernate会覆盖数据库返回的主键值的原因。
但是,如果hibernate具有关闭这种行处理逻辑的功能,那么它可能会有所帮助。
希望这有帮助!