Wan*_*ker 5 java spring hibernate jpa spring-data
使用 Spring-Data 与 Hibernate 观察到的问题 - Spring 4.1.5.RELEASE、Spring-Data - 1.8.0.RELEASE、Hibernate - 4.3.8.Final
公司域名以 .in 结尾,就像在印度一样。因此,我的 Java 包以“in.something ....”开头。
使用 JPA 存储库时,如果我必须对如下方法使用自定义查询:
@Query(value = "SELECT o FROM UserEntity o, UserAttribute u where o.organization.organizationType.code in ?1 and o.status in ?2 and u.attrKey = 'SOL_ID' and u.attrValue in ?3 and u.userEntity = o")
Page<UserEntity> findByOrganizationAndStatusAndSolId(List<String> organizationTypes, List<StatusMaster> statusList, List<String> solId, Pageable pageable);
Run Code Online (Sandbox Code Playgroud)
应用程序启动失败,因为 JPA 查询具有类的完全限定名称,并且由于包以“in”开头,因此它认为存在验证错误。
引起原因:java.lang.IllegalArgumentException:org.hibernate.hql.internal.ast.QuerySyntaxException:期望打开,发现“。” 靠近第 1 行第 44 列 [SELECT o FROM in.something.UserEntity o, in.something.UserAttribute u where o.organization.organizationType.code in ?1 和 o.status in ?2 and u.attrKey = 'SOL_ID' and u.attrValue in ?3 和 u.userEntity = o]
Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract org.springframework.data.domain.Page in.something.UserRepository.findByOrganizationAndStatusAndSolId(java.util.List,java.util.List,java.util.List,org.springframework.data.domain.Pageable)!
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:97)
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:66)
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.fromQueryAnnotation(SimpleJpaQuery.java:169)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:114)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:160)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:68)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:290)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:158)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:162)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:44)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142)
... 37 more
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: expecting OPEN, found '.' near line 1, column 44 [SELECT o FROM in.something.UserEntity o, in.something.UserAttribute u where o.organization.organizationType.code in ?1 and o.status in ?2 and u.attrKey = 'SOL_ID' and u.attrValue in ?3 and u.userEntity = o]
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1364)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:294)
Run Code Online (Sandbox Code Playgroud)
我尝试了多种选择,但没有运气:
<delimited-identifiers/>对此的任何意见都将受到高度赞赏。
更新: 当我的包以“com.something”开头时,代码曾经工作正常。但是,我重构了代码来修复包名称,之后问题开始出现
UPDATE 2
如果查询被修改为使用,SELECT o FROM UserEntity o JOIN o.attributes u...那么错误就会消失。
更新 3 - 更新中也发现了问题
@Query(value="UPDATE WebSessionEntity o SET o.lastAccessedOn = ?2 WHERE o.authSessionToken = ?1")
public int updateLastAccessedOn(String authSessionToken, Date accessDate);
Run Code Online (Sandbox Code Playgroud)
假设 WebSessionEntity 以包名称“in.something...”启动,则应用程序不会启动。在启动过程中,我收到 Hibernate 验证错误:
2015-03-24 18:52:00,810 [main] ERROR org.hibernate.hql.internal.ast.ErrorCounter - line 1:8: unexpected token: in line 1:8: unexpected token: in
at org.hibernate.hql.internal.antlr.HqlBaseParser.updateStatement(HqlBaseParser.java:210)
...
...
Caused by: java.lang.IllegalArgumentException: node to traverse cannot be null!
at org.hibernate.hql.internal.ast.util.NodeTraverser.traverseDepthFirst(NodeTraverser.java:63)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:272)
Run Code Online (Sandbox Code Playgroud)
按照惯例,当域名干扰包的命名时,使用下划线。
链接 - https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html
链接的摘录,
在某些情况下,互联网域名可能不是有效的包名称。如果域名包含连字符或其他特殊字符,如果程序包名称以数字或其他不能用作 Java 名称开头的字符开头,或者如果程序包名称包含保留的 Java 关键字,则可能会发生这种情况。例如“int”。在这种情况下,建议的约定是添加下划线。
| 归档时间: |
|
| 查看次数: |
1722 次 |
| 最近记录: |