Hi, Please create a pull request and we will review it in more detail.
Colm. On Fri, Jan 11, 2019 at 1:28 PM Matteo Rulli <[email protected]> wrote: > Hello, > > We use JAX-RSSearch and Fiql parser in a JAX-RS endpoint and we have a > problem with org.apache.cxf.jaxrs.ext.search.Beanspector. > > Let's consider the following pojos: > > public class A { > > private String value; > > public String getValue(){ ... } > public void setValue(String value) { ... } > } > > public class B { > > private A aValue; > > public A getAValue(){ ... } > public void setAValue(A avalue) { ... } > } > > And assume one extends these pojos and decorates them with JPA > annotations. > > To leverage CXF org.apache.cxf.jaxrs.ext.search.SearchContext and > JPACriteriaQueryVisitor as explained in the docs ( > http://cxf.apache.org/docs/jax-rs-search.html#JAX-RSSearch-JPA2.0) and > perform searches like > > _s=aValue==*search token* > > in OpenJPA one has to override the EntityB.getAValue as follows: > > @Entity > // ... other JPA annotations are omitted > public class EntityB extends B { > > @Override > // We need to specialize return type to EntityA to make > SearchContext work > public EntityA getAValue(){ ... } > > // This method definition is needed to avoid java.lang.VerifyError > from JPA provider > public void setAValue(EntityA avalue) { ... } > } > > But with this scenario, the current implementation of > org.apache.cxf.jaxrs.ext.search.Beanspector<T> fails, throwing > IllegalArgumentException: Accessor 'aValue' type mismatch, getter type is X > while setter type is Y, X and Y depending on the order of the EntityB's > methods as returned by the Class.getMethods(). > > This is the current implementation of Beanspector where the exception is > triggered: > > @SuppressWarnings("unchecked") > private void init() { > if (tclass == null) { > tclass = (Class<T>)tobj.getClass(); > } > for (Method m : tclass.getMethods()) { > if (isGetter(m)) { > getters.put(getPropertyName(m), m); > } else if (isSetter(m)) { > setters.put(getPropertyName(m), m); > } > } > // check type equality for getter-setter pairs > Set<String> pairs = new HashSet<>(getters.keySet()); > pairs.retainAll(setters.keySet()); > for (String accessor : pairs) { > Class<?> getterClass = getters.get(accessor).getReturnType(); > Class<?> setterClass = > setters.get(accessor).getParameterTypes()[0]; > if (!getterClass.equals(setterClass)) { > throw new IllegalArgumentException(String > .format("Accessor '%s' type mismatch, getter type is %s > while setter type is %s", > accessor, getterClass.getName(), > setterClass.getName())); > } > } > } > > And this is how we patched it: > > @SuppressWarnings("unchecked") > private void init() { > if (tclass == null) { > tclass = (Class<T>)tobj.getClass(); > } > for (Method m : tclass.getMethods()) { > if (isGetter(m)) { > String pname = getPropertyName(m); > if (!getters.containsKey(pname)) { > getters.put(getPropertyName(m), m); > } else { > // Prefer the getter that has the most specialized > class as a return type > Method _m = getters.get(pname); > if > (_m.getReturnType().isAssignableFrom(m.getReturnType())) { > getters.put(pname, m); > } > } > } else if (isSetter(m)) { > String pname = getPropertyName(m); > if (!setters.containsKey(pname)) { > setters.put(getPropertyName(m), m); > } else { > // Prefer the setter that has the most specialized > class as a parameter > Method _m = setters.get(pname); > if > (_m.getParameterTypes()[0].isAssignableFrom(m.getParameterTypes()[0])) { > setters.put(pname, m); > } > } > } > } > // check type equality for getter-setter pairs > Set<String> pairs = new HashSet<>(getters.keySet()); > pairs.retainAll(setters.keySet()); > for (String accessor : pairs) { > Class<?> getterClass = getters.get(accessor).getReturnType(); > Class<?> setterClass = > setters.get(accessor).getParameterTypes()[0]; > if (!setterClass.isAssignableFrom(getterClass)) { > throw new IllegalArgumentException(String > .format("Accessor '%s' type mismatch, getter type is %s > while setter type is %s", > accessor, getterClass.getName(), > setterClass.getName())); > } > } > } > > If you think this is OK we can create a pull request with this. > > Thank you, > Matteo -- Colm O hEigeartaigh Talend Community Coder http://coders.talend.com
