my2iu / Jinq

LINQ-style queries for Java 8
Other
659 stars 71 forks source link

bug on where(p->p.isReadOnly()==true) Could not analyze lambda code #77

Open kindywu opened 5 years ago

kindywu commented 5 years ago

JPAJinqStream query = this.streamAll(DictionaryCategory.class); List list = query.where(p.isDeleted() == true).toList(); failure[Could not analyze lambda code] use the isReadOnly also occur the same error @my2iu jdk:1.8.0_181 springboot:2.1.0.RELEASE

image

image image image

my2iu commented 5 years ago

I would have to see the full stack trace to see what the error is. I suspect the problem is that Jinq can't determine the name of your boolean methods. When you use field-based annotations in JPA, Jinq has to guess the names of the getter methods. For the field "isReadyOnly", I think Jinq is guessing that the getter method is either "isIsReadyOnly" or "getIsReadOnly" but the actual getter method is "isReadOnly."

For this case, you will have to manually tell Jinq what the name of the getter method is

this.registerAssociationAttribute( 
   DictionaryCategory.class.getMethod("isReadOnly"), "isReadOnly", false));

You might have to do this on all the entities that inherit from BaseEntity.

kindywu commented 5 years ago

java.lang.IllegalArgumentException: Could not analyze lambda code at org.jinq.jpa.transform.LambdaAnalysis.fullyAnalyzeLambda(LambdaAnalysis.java:197) at org.jinq.jpa.transform.LambdaInfo.fullyAnalyze(LambdaInfo.java:116) at org.jinq.jpa.JPAQueryComposer.applyTransformWithLambda(JPAQueryComposer.java:283) at org.jinq.jpa.JPAQueryComposer.where(JPAQueryComposer.java:449) at org.jinq.jpa.JPAQueryComposer.where(JPAQueryComposer.java:63) at org.jinq.orm.stream.QueryJinqStream.where(QueryJinqStream.java:45) at org.jinq.jpa.QueryJPAJinqStream.where(QueryJPAJinqStream.java:106) at com.tencent.demo.services.DictionaryService.queryDictionaryCategory2(DictionaryService.java:46) at com.tencent.demo.services.DictionaryService$$FastClassBySpringCGLIB$$9b9c0c64.invoke() at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:119) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88) at com.tencent.demo.services.interceptors.PerfInterceptor.doPerf(PerfInterceptor.java:18) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644) at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633) at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) at com.tencent.demo.services.DictionaryService$$EnhancerBySpringCGLIB$$45b82fbb.queryDictionaryCategory2() at com.tencent.demo.DictionaryTest.testDictionaryCategory(DictionaryTest.java:65) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74) at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) 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:190) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209) Caused by: org.jinq.rebased.org.objectweb.asm.tree.analysis.AnalyzerException: Unknown method com/tencent/demo/model/dbs/DictionaryCategory:isDeleted()Z encountered at ch.epfl.labos.iu.orm.queryll2.symbolic.BasicSymbolicInterpreter.naryOperation(BasicSymbolicInterpreter.java:367) at org.jinq.rebased.org.objectweb.asm.tree.analysis.Frame.execute(Frame.java:613) at ch.epfl.labos.iu.orm.queryll2.path.CodePath.calculateReturnValueAndConditions(CodePath.java:148) at ch.epfl.labos.iu.orm.queryll2.path.TransformationClassAnalyzer.analyzeMethod(TransformationClassAnalyzer.java:510) at ch.epfl.labos.iu.orm.queryll2.path.TransformationClassAnalyzer.analyzeLambdaMethod(TransformationClassAnalyzer.java:476) at org.jinq.jpa.transform.LambdaAnalysis.analyzeLambda(LambdaAnalysis.java:318) at org.jinq.jpa.transform.LambdaAnalysis.fullyAnalyzeLambda(LambdaAnalysis.java:187) ... 63 more

kindywu commented 5 years ago

i try your way ,but it also throw the same exception @my2iu

protected JinqJPAStreamProvider streams;

@PersistenceUnit public void setEntityManagerFactory(EntityManagerFactory emf) throws Exception { streams = new JinqJPAStreamProvider(emf); } public void queryDictionaryCategory2() throws NoSuchMethodException, SecurityException { //here @my2iu
streams.registerAssociationAttribute(DictionaryCategory.class.getMethod("isDeleted"), "isDeleted", false); JPAJinqStream query = this.streamAll(DictionaryCategory.class); List<Pair<Integer, String>> list = query.where(p -> p.isDeleted()).select(p -> new Pair<>(p.getId(), p.getName())).toList(); for (Pair<Integer, String> c : list) { System.out.println(c.getTwo()); } }

my2iu commented 5 years ago

You can see from the stack trace here that it doesn’t recognize the isDeleted() method:

Caused by: org.jinq.rebased.org.objectweb.asm.tree.analysis.AnalyzerException: Unknown method com/tencent/demo/model/dbs/DictionaryCategory:isDeleted()Z encountered

Manually registering it should allow Jinq to recognize the method. I’m not sure why it’s not working for you. Are you sure you’re registering on the same JinqJPAStreamProvider that you are calling the query on? You register isDeleted on “streams”, but you use “this” to create the query. Do they refer to the same object?

kindywu commented 5 years ago

yes,i'am sure the same object.i copy them from difference file.the stream var is define in baseservice class,and use in the DictionaryService isDeleted is java convention image

image

@my2iu the java code file is in the .zip Desktop.zip

my2iu commented 5 years ago

I always get the convention wrong too. I think the official convention is that the variable is called deleted and the getter is called isDeleted.

Anyway, the problem is that when you call registerAssociationAttribute(), Jinq actually ends up registering the method BaseEntity.isDeleted() because that's where the method is defined. The method that is actually called is DictionaryCategory.isDeleted() though, so that's where Jinq is getting confused. You have to use the alternate registration method:

streams.registerAssociationAttribute(DictionaryCategory.class.getMethod("isDeleted"), DictionaryCategory.class, "isDeleted", false);
kindywu commented 5 years ago

ok,i get it,thanks