java - Is it possible to use Predicate<T> when creating queries for Jinq? -


my question jinq , , using version 1.8.9 latest release.

i trying use jinq implementing general reusable jpa (java persistence api) typesafe query method java 8 lambda (functional interface) predicate method parameter.

unfortunately, can not make work java 8 predicate instead can use similar predicate type (provided jinq) method parameter, avoid dependencies jinq in method signatures, , therefore prefer java 8 predicate if possible?

jinq provides functional interface "where":

package org.jinq.orm.stream; public interface jinqstream<t> extends stream<t> {     @functionalinterface     public static interface where<u, e extends exception> extends serializable {       public boolean where(u obj) throws e;     } 

i can implement query method want (but undesirable coupling) using above interface in method signature this:

public list<t> select(jinqstream.where<t, exception> wherepredicate) 

instead of above coupling jinq in method signature use standard predicate below:

public list<t> select(java.util.function.predicate<t> wherepredicate) { 

the standard predicate defined this:

@functionalinterface public interface predicate<t> {   public boolean test(t t); } 

therefore thought might have been possible implement desired select method using following code creating lambda implementation of jinq interface:

public list<t> select(java.util.function.predicate<t> predicate) {     org.jinq.orm.stream.jinqstream.where<t, exception> wherepredicate = u -> predicate.test(u);     ... 

however, not work results in illegalargumentexception (see stacktrace pasted further down below)

below more code illustrating trying do.

the problem trying illustrate want use predicate parameter in below method "datamapperbase.select2" instead of jinq specific parameter in below method "datamapperbase.select".

public abstract class datamapperbase<t> {     ...     private entitymanagerfactory entitymanagerfactory;     private entitymanager entitymanager;     private final class clazz;// initialized using below method getclazz()      private class getclazz() throws classnotfoundexception {         type genericsuperclass = getclass().getgenericsuperclass();         type actualtypeargument = ((parameterizedtype)genericsuperclass).getactualtypearguments()[0];         return class.forname(actualtypeargument.gettypename());     }      // method works has undesirable dependency jinq in method signature.     public list<t> select(org.jinq.orm.stream.jinqstream.where<t, runtimeexception> wherepredicate) {         jinqjpastreamprovider streams = new jinqjpastreamprovider(entitymanagerfactory);         list<t> result = streams           .streamall(entitymanager, clazz)           .where( wherepredicate )           .tolist();         return result;     }          // instead of above select method want use below method (currently named "select2")      // code below compiles not work in runtime.this method signature use.     public list<t> select2(java.util.function.predicate<t> predicate) {         org.jinq.orm.stream.jinqstream.where<t, runtimeexception> wherepredicate = u -> predicate.test(u);             jinqjpastreamprovider streams = new jinqjpastreamprovider(entitymanagerfactory);         list<t> result = streams           .streamall(entitymanager, clazz)           .where( wherepredicate )           .tolist();         return result;     } ... public class persondatamapper extends datamapperbase<person> { ... ... @entity @access(accesstype.property) @table(name="person") public class person implements serializable {     ...     private int age;     @column(name = "age")     public int getage() {         return age;     }     public void setage(int age) {         this.age = age;     }     ...  ... // invocations below can used e.g. test class list<person> persons  = persondatamapper.select( p -> p.getage() > 20 ); list<person> persons2 = persondatamapper.select2( p -> p.getage() > 20 ); 

both above methods (select , select2) compiles second fails in runtime following exception;

java.lang.illegalargumentexception: not extract code lambda. error occurs because lambda references objects aren't serializable.     @ org.jinq.jpa.transform.lambdainfo.analyze(lambdainfo.java:33)     @ org.jinq.jpa.transform.lambdaanalysisfactory.extractsurfaceinfo(lambdaanalysisfactory.java:7)     @ org.jinq.jpa.jpaquerycomposer.applytransformwithlambda(jpaquerycomposer.java:269)     @ org.jinq.jpa.jpaquerycomposer.where(jpaquerycomposer.java:365)     @ org.jinq.jpa.jpaquerycomposer.where(jpaquerycomposer.java:1)     @ org.jinq.orm.stream.queryjinqstream.where(queryjinqstream.java:45)     @ org.jinq.jpa.queryjpajinqstream.where(queryjpajinqstream.java:86) 

the error message indicates might problem java.util.function.predicate not implementing serializable. (since person in example implements serializable)

though, experimented interface this:

public interface predicate2<t> extends java.util.function.predicate<t> , serializable {} 

when used instead, got following exception:

java.lang.illegalargumentexception: not analyze lambda code     @ org.jinq.jpa.transform.lambdaanalysis.fullyanalyzelambda(lambdaanalysis.java:197)     @ org.jinq.jpa.transform.lambdainfo.fullyanalyze(lambdainfo.java:116)     @ org.jinq.jpa.jpaquerycomposer.applytransformwithlambda(jpaquerycomposer.java:278)     @ org.jinq.jpa.jpaquerycomposer.where(jpaquerycomposer.java:365)     @ org.jinq.jpa.jpaquerycomposer.where(jpaquerycomposer.java:1)     @ org.jinq.orm.stream.queryjinqstream.where(queryjinqstream.java:45)     @ org.jinq.jpa.queryjpajinqstream.where(queryjpajinqstream.java:86)     

so, question if can provide working implementation of above method "datamapperbase.select2" i.e. method using parameter java.util.function.predicate ?

due limitations of java 8's implementation of lambdas, jinq requires use of serializable lambdas. unfortunately, default predicate in java 8 not serializable, cannot analyzed jinq.

i gave talk @ jvm language summit last year on how jinq works. section on why default java 8 predicate couldn't used jinq discussed @ around 17:16 mark:

https://youtu.be/jqcnzfztr2i?t=17m16s

the current jinq bytecode analysis designed work jinq query style, if try stuff in arbitrary lambdas, jinq's analysis fail. that's discussed elsewhere in video.


Comments

Popular posts from this blog

get url and add instance to a model with prefilled foreign key :django admin -

css - Make div keyboard-scrollable in jQuery Mobile? -

ruby on rails - Seeing duplicate requests handled with Unicorn -