I want to perform a tree-grouping from query result set using Lambdaj. Results come from Hibernate.
I can do aggregation successfully, but then code fails on grouping:
List<MyClass> list = myDao.findByProperty(value);
Integer intAvg = avg(list, on(MyClass.class).getIntProperty()); //OK
Group<MyClass> group = group(list, on(MyClass.class).getGroupingStringProperty()); //FAIL
Exception is
ch.lambdaj.util.IntrospectionException: java.lang.NoSuchMethodException: org.example.entityMyClass.-2147483644()
at ch.lambdaj.util.IntrospectionUtil.getPlainPropertyValue(IntrospectionUtil.java:61)
at ch.lambdaj.util.IntrospectionUtil.getBooleanPropertyValue(IntrospectionUtil.java:53)
at ch.lambdaj.util.IntrospectionUtil.getPropertyValue(IntrospectionUtil.java:45)
at ch.lambdaj.group.StringGroupCondition.getGroupValue(StringGroupCondition.java:41)
at ch.lambdaj.group.GroupImpl.addItem(GroupImpl.java:28)
at ch.lambdaj.group.Groups.group(Groups.java:58)
at ch.lambdaj.group.Groups.group(Groups.java:46)
at ch.lambdaj.Lambda.group(Lambda.java:1237)
at org.example.package.Class.method(Class.java:128)
...............
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:190)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoSuchMethodException: org.example.entityMyClass.-2147483644()
at java.lang.Class.getMethod(Class.java:1665)
at ch.lambdaj.util.IntrospectionUtil.getPlainPropertyValue(IntrospectionUtil.java:59)
... 91 more
I tried to do some homework, unsuccessfully for now.
Lambdaj uses cglib
to perform proxying. Ivy file provides a cglib-nodep.jar
package. Our architecture project features (because of dependency with Hibernate) cglib
standard release and asm-all
. Please note that, due to company policy, our Ivy dependency file does not allow transitive dependency, and dependencies are decided by the dev team based on the real needs of the projects (so if Hibernate requires a certain version of cglib
, we put that dependency into Ivy and mark everything as non-transitive).
So in my project I have <dependency org="com.googlecode.lambdaj" name="lambdaj" rev="2.3.3"/>
(transitive true by default) and my architecture project, on which my project depends, has
<dependency org="org.ow2.asm" name="asm-all" rev="4.0" transitive="false"/>
<dependency org="org.hibernate" name="hibernate-core" rev="4.1.6.Final" transitive="false"/>
<dependency org="org.hibernate" name="hibernate-ehcache" rev="4.1.6.Final" transitive="false"/>
<dependency org="org.hibernate" name="hibernate-validator" rev="4.3.0.Final" transitive="false"/>
<dependency org="org.hibernate.javax.persistence" name="hibernate-jpa-2.0-api" rev="1.0.1.Final" transitive="false"/>
(and a lot more)
The question is: am I doing something wrong in the code? Is that an issue with Hibernate?
Trivial mistake
The API must be invoked not as
Group<MyClass> group = group(list, on(MyClass.class).getGroupingStringProperty());
but rather
Group<MyClass> group = group(list, by(on(MyClass.class).getGroupingStringProperty()));
Notice group
...by
syntax