Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid derived query! No property XXX found for type YYY! #26

Open
bladethirst opened this issue Jun 15, 2018 · 7 comments
Open

Invalid derived query! No property XXX found for type YYY! #26

bladethirst opened this issue Jun 15, 2018 · 7 comments

Comments

@bladethirst
Copy link

你好!我的开发工具为Spring Source Tool Suite。

  1. 我在项目中按说明使用了@TemplateQuery,在REPO接口中,会提示查找的对象没有属性。当我的代码是这样
    public interface ApmObjThresSnapshotRepo extends BaseDao<ApmObjThresSnapshot, String> {
    @TemplateQuery
    public Page<Map<String, Object>> findMgedobjThresSnapshot(ApmObjThresSnapshot snap, Pageable pageable);

    @TemplateQuery
    public List<Map<String, Object>> findMgedobjThresSnapshot();
    }
    时,启动会提示
    Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract org.springframework.data.domain.Page com.set.me.repo.apm.ApmObjThresSnapshotRepo.findMgedobjThresSnapshot(com.set.me.model.apm.ApmObjThresSnapshot,org.springframework.data.domain.Pageable)! No property findMgedobjThresSnapshot found for type ApmObjThresSnapshot!

  2. 我直接clone您的spring-data-jpa-extra到本地, 运行Test代码,会提示
    11:11:52.378 [main] ERROR org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@1a04f701] to prepare test instance [com.slyak.spring.jpa.JpaTest@63021689]
    java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in com.slyak.spring.jpa.AppConfig: Invocation of init method failed; nested exception is java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1080)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:857)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:106)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:249)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
    ... 25 common frames omitted
    Caused by: java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
    at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724)
    at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531)
    at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
    at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
    at java.lang.Class.createAnnotationData(Class.java:3521)
    at java.lang.Class.annotationData(Class.java:3510)
    at java.lang.Class.getAnnotation(Class.java:3415)
    at java.lang.reflect.AnnotatedElement.isAnnotationPresent(AnnotatedElement.java:258)
    at java.lang.Class.isAnnotationPresent(Class.java:3425)
    at org.hibernate.annotations.common.reflection.java.JavaAnnotationReader.isAnnotationPresent(JavaAnnotationReader.java:50)
    at org.hibernate.annotations.common.reflection.java.JavaXAnnotatedElement.isAnnotationPresent(JavaXAnnotatedElement.java:60)
    at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.categorizeAnnotatedClass(AnnotationMetadataSourceProcessorImpl.java:115)
    at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.(AnnotationMetadataSourceProcessorImpl.java:104)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.(MetadataBuildingProcess.java:147)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:141)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:847)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:874)
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:360)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:382)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:371)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:336)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
    ... 40 common frames omitted
    11:11:52.390 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - After test class: context [DefaultTestContext@6f96c77 testClass = JpaTest, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@be64738 testClass = JpaTest, locations = '{}', classes = '{class com.slyak.spring.jpa.AppConfig}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], class annotated with @DirtiesContext [false] with mode [null].

@stormning
Copy link
Collaborator

stormning commented Jun 15, 2018 via email

@bladethirst
Copy link
Author

@stormning 感谢你的超快速答复!
目前我的项目用的是spring-boot 2.0.2版本,多数据源形式。
关于上面两个问题,第2个问题,我用您的2.1.2.RELEASE分支,可以测试通过。
第1个问题,我maven依赖上面的2.1.2.RELEASE的jar包,之前我用的是继承BaseDao,BaseDao继承了您的GenericJpaRepository,和另外的PagingAndSortingRepository、JpaSpecificationExecutor。测试过了还是报同样的spring data jpa找不到实体属性的错。单独写一个Repo只继承GenericJpaRepository,也是报同样的错。
堆栈如下:
Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract org.springframework.data.domain.Page com.set.me.repo.apm.ApmObjThresSnapshotNativeRepo.findMgedobjThresSnapshot(com.set.me.model.apm.ApmObjThresSnapshot,org.springframework.data.domain.Pageable)! No property findMgedobjThresSnapshot found for type ApmObjThresSnapshot!
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.(PartTreeJpaQuery.java:82) ~[spring-data-jpa-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:103) ~[spring-data-jpa-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:208) ~[spring-data-jpa-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:79) ~[spring-data-jpa-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lookupQuery(RepositoryFactorySupport.java:553) ~[spring-data-commons-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$mapMethodsToQuery$1(RepositoryFactorySupport.java:546) ~[spring-data-commons-2.0.7.RELEASE.jar:2.0.7.RELEASE]
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[na:1.8.0_162]

我再查看了您项目的源码后,推测您的动态查询应该是由com.slyak.spring.jpa.TemplateQueryLookupStrategy这个类来解析的吧,对应上面错误堆栈中的org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy.AbstractQueryLookupStrategy,

请问除了GIT上列出的配置外,还需要其他配置吗?我觉得是添加了@TemplateQuery也没有使用TemplateQueryLookupStrategy来解析的原故。

@bladethirst
Copy link
Author

@stormning 我把代码集成到项目中去,发现很多类已经不能用了,应该是和spring-data-jpa不兼容了。在spring-boot2.0.2中,spring-data-jpa已经是2.0.7.release版本,很多类的写法已经变了。
请问一下,spring-data-jpa有升级适配spring-data-jpa2.x的计划吗?非常期待您们的作品!

@bladethirst
Copy link
Author

bladethirst commented Jun 15, 2018

@stormning 大神你好!再打扰一下。
目前我集成到spring-boot.2.0.2版本后,通过修改spring-data-jpa的代码后已经可以在项目中正常运行了。目前还有一个小小的问题。
您的测试代码中com.slyak.spring.jpa.JpaTest.findByTemplateQueryWithTemplateQueryObject(),用到的对象是com.slyak.spring.jpa.SampleQuery,这里设置content的值,用的是
public void setContent(String content) {
if (content != null) {
this.content = "%" + content + "%";
}
}
所以在.sftl中
--countContent
SELECT count(*) FROM t_sample WHERE 1 = 1
<#if content??>
AND content LIKE :content
</#if>
content是直接带有%%号的,但是在实际使用过程中,像content这样的内容字段,肯定是不会前后带%的吧。那么问题就来了,在正常的spring-data-jpa中,@query注解里面写like查询是可以用 where column like %:value%这样来写的,但是现在在.sftl中像这样写就会报错,提示ERROR: syntax error at or near "%",请问现在spring-data-jpa-extra不支持这样的写法吗???
盼答复,甚为感谢!

@stormning
Copy link
Collaborator

正常的spring-data-jpa也是不能%:value%这样写的吧,是也:value,然后传入值的时候自己加%,因为:value会转成preparedStatement,如果是%:value%,最后的结果就变成了 where content like %‘x x x’% ,是错误的sql,所以只能填:value,%是自己传参数的时候加

@bladethirst
Copy link
Author

你好!感谢答复。
我查了现在项目中的写法,spring-data-jpa是可以用%:value%这样的来查询的。
我的请求是:/amattribute/findAmAttrResource?resourcetype=Ac&sort=resourcetype&order=asc&offset=0&
Controller层:
@RequestMapping("findAmAttrResource")
public @responsebody PageImpl<Map<String, String>> findAmAttr4Choose(AmAttribute attribute, HttpServletRequest req,
HttpServletResponse res) {
List<Map<String, String>> result = new ArrayList<Map<String, String>>();
Page page = null;
Sort sort = new Sort(Direction.ASC, "resourcetype");
Pageable pageable = PropertyFilter.buildPageableFromHttpRequest(req, sort);
page = service.findAmAttrResource(attribute.getResourcetype(), new BigDecimal(0), pageable);
for (String resType : page.getContent()) {
Map<String, String> m = new HashMap<String, String>();
m.put("resourcetype", resType);
result.add(m);
}
PageImpl<Map<String, String>> newPage = new PageImpl<>(result, pageable, page.getTotalElements());
return newPage;
}

Service层:
public Page findAmAttrResource(String resourcetype, BigDecimal type, Pageable pageable) {
if (StringUtils.isEmpty(resourcetype)) {
return repo.findDistinctResourcetype(type, pageable);
} else {
return repo.findDistinctResourcetype(resourcetype, type, pageable);
}
}

Repo层:
@query(value = "select distinct resourcetype from AmAttribute a where resourcetype like %:resourcetype% and type=:type")
public Page findDistinctResourcetype(@param("resourcetype") String resourcetype,
@param("type") BigDecimal type, Pageable pageable);

当然这些都是在未发现您的项目之前,我的service层用了比较丑的代码,如果条件一多就晕掉了。
所以,很感谢你的项目,现在可以像Mybatis那样根据对象属性是否为空,来动态设置查询条件。

@329009099
Copy link

666

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants