java - Hibernate HQL Projection Issue with Set Using AliasToBeanResultTransformer -
i having problem hibernate hql projection using aliastobeanresulttransformer, result trying homecoming isn't beingness mapped bean, here situation:
the hql query using this:
class="lang-sql prettyprint-override">select entity.categorytypes categorytypes nz.co.doltech.ims.server.entities.incidententity entity (entity.id = :id105019) i want categorytype's incidententity based on bring together relationship. works fine when i'm not attempting utilize transformer on it. categorytypes set , transformer keeps trying check method's parameter types , fails because instead of finding categorytypeentity finds java.util.set if trying map single categorytypeentity categorytypes field. have thought because set pull info out set , seek map categorytypes field. apparently not though.
@javax.persistence.entity(name = "incidents") @cache(usage=cacheconcurrencystrategy.transactional) public class incidententity implements entity { ... @manytomany(fetch = fetchtype.lazy) @jointable(name = "incident_categorytype", joincolumns = { @joincolumn(name = "incident_id", nullable = false, updatable = false) }, inversejoincolumns = { @joincolumn(name = "categorytype_id", nullable = false, updatable = false) }) private set<categorytypeentity> categorytypes = new hashset<categorytypeentity>(); ... public set<categorytypeentity> getcategorytypes() { homecoming categorytypes; } public void setcategorytypes(set<categorytypeentity> categorytypes) { this.categorytypes = categorytypes; } } here phone call make:
class="lang-java prettyprint-override">query query = session.createquery("select entity.categorytypes categorytypes nz.co.doltech.ims.server.entities.incidententity entity " + "where (entity.id = :id105019)") query.setresulttransformer(transformers.aliastobean(incidententity.class)); homecoming query.list(); the exceptions are:
caused by: org.hibernate.propertyaccessexception: illegalargumentexception occurred while calling setter of nz.co.doltech.ims.server.entities.incidententity.categorytypes ... caused by: java.lang.illegalargumentexception: argument type mismatch and hibernate log message is:
jun 27, 2014 12:32:11 org.hibernate.property.basicpropertyaccessor$basicsetter set severe: illegalargumentexception in class: nz.co.doltech.ims.server.entities.incidententity, setter method of property: categorytypes jun 27, 2014 12:32:11 org.hibernate.property.basicpropertyaccessor$basicsetter set severe: expected type: java.util.set, actual value: nz.co.doltech.ims.server.entities.categorytypeentity using hibernate 3.6.10
can see going on here? doesn't seem normal behavior, perhaps have done wrong. appreciate help can get!
update: strange, not straight related issue. when have hibernates use_query_cache property set true maintain getting projection result null in aliastobeanresulttransformer (then result returns null (or [null, null, null] depending on how many returned. think might bug? in regards issue @ hand, when remove result transformer returns 3 categorytypeentites expected. when added 1 categorytypeentity that's beingness processed in transformers transformtuple method. confused both of these issues.
cheers, ben
manage resolve issue rewriting aliastobeanresulttransformer class. not insert collection if collection types match , collections generic type match. found great nested bean transformer create samiandoni allow me map nested projection values :) here how implemented else having same issue:
class="lang-java prettyprint-override">@suppresswarnings({"serial","rawtypes"}) public class aliastobeanresulttransformer implements resulttransformer, serializable { // impl note : due delayed population of setters (setters cached // performance), cannot define equality // transformer private final class resultclass; private boolean isinitialized; private string[] aliases; private setter[] setters; private getter[] getters; public aliastobeanresulttransformer(class resultclass) { if ( resultclass == null ) { throw new illegalargumentexception( "resultclass cannot null" ); } isinitialized = false; this.resultclass = resultclass; } @override public object transformtuple(object[] tuple, string[] aliases) { object result; seek { if ( ! isinitialized ) { initialize( aliases ); } else { check( aliases ); } result = resultclass.newinstance(); ( int = 0; < aliases.length; i++ ) { setter setter = setters[i]; if ( setter != null ) { class paramtype = setter.getmethod().getparametertypes()[0]; if(paramtype != null) { object obj = tuple[i]; // check if parameter collection if(!obj.getclass().equals(paramtype) && iscollection(paramtype)) { inserttolist(result, obj, getters[i], aliases[i]); } else { setter.set( result, obj, null ); } } } } } grab ( instantiationexception e ) { throw new hibernateexception( "could not instantiate resultclass: " + resultclass.getname() ); } grab ( illegalaccessexception e ) { throw new hibernateexception( "could not instantiate resultclass: " + resultclass.getname() ); } homecoming result; } @override public list transformlist(list collection) { homecoming collection; } @suppresswarnings("unchecked") private boolean inserttolist(object result, object obj, getter getter, string alias) { class genclass; seek { genclass = reflectutils.getgenerictype(resultclass.getdeclaredfield(alias)); // check if collection can take obj if(genclass.equals(obj.getclass())) { collection collection = (collection) getter.get(result); collection.add(obj); homecoming true; } } grab (nosuchfieldexception | securityexception e) {} homecoming false; } private void initialize(string[] aliases) { propertyaccessor propertyaccessor = new chainedpropertyaccessor( new propertyaccessor[] { propertyaccessorfactory.getpropertyaccessor( resultclass, null ), propertyaccessorfactory.getpropertyaccessor( "field" ) } ); this.aliases = new string[ aliases.length ]; setters = new setter[ aliases.length ]; getters = new getter[ aliases.length ]; ( int = 0; < aliases.length; i++ ) { string alias = aliases[ ]; if ( alias != null ) { this.aliases[ ] = alias; setters[ ] = propertyaccessor.getsetter( resultclass, alias ); getters[ ] = propertyaccessor.getgetter( resultclass, alias ); } } isinitialized = true; } private void check(string[] aliases) { if ( ! arrays.equals( aliases, this.aliases ) ) { throw new illegalstateexception( "aliases different cached; aliases=" + arrays.aslist( aliases ) + " cached=" + arrays.aslist( this.aliases ) ); } } private boolean iscollection(class clazz) { homecoming collection.class.isassignablefrom(clazz); } public boolean equals(object o) { if ( == o ) { homecoming true; } if ( o == null || getclass() != o.getclass() ) { homecoming false; } aliastobeanresulttransformer = ( aliastobeanresulttransformer ) o; if ( ! resultclass.equals( that.resultclass ) ) { homecoming false; } if ( ! arrays.equals( aliases, that.aliases ) ) { homecoming false; } homecoming true; } public int hashcode() { int result = resultclass.hashcode(); result = 31 * result + ( aliases != null ? arrays.hashcode( aliases ) : 0 ); homecoming result; } } you need implement refectutil method too:
class="lang-java prettyprint-override">public static class<?> getgenerictype(field field) { parameterizedtype type = (parameterizedtype) field.getgenerictype(); homecoming (class<?>) type.getactualtypearguments()[0]; } then can create work samiandoni's transformer (just ensure using edited aliastobeanresulttransformer class):
class="lang-java prettyprint-override">/** * @author samiandoni * */ @suppresswarnings("rawtypes") public class aliastobeannestedresulttransformer implements resulttransformer, serializable { private static final long serialversionuid = -8047276133980128266l; private final class<?> resultclass; public aliastobeannestedresulttransformer(class<?> resultclass) { this.resultclass = resultclass; } @suppresswarnings("unchecked") public object transformtuple(object[] tuple, string[] aliases) { map<class<?>, list<?>> subclasstoalias = new hashmap<class<?>, list<?>>(); list<string> nestedaliases = new arraylist<string>(); seek { (int = 0; < aliases.length; i++) { string alias = aliases[i]; if (alias.contains(".")) { nestedaliases.add(alias); string[] sp = alias.split("\\."); string fieldname = sp[0]; string aliasname = sp[1]; class<?> subclass = resultclass.getdeclaredfield(fieldname).gettype(); if (!subclasstoalias.containskey(subclass)) { list<object> list = new arraylist<object>(); list.add(new arraylist<object>()); list.add(new arraylist<string>()); list.add(fieldname); subclasstoalias.put(subclass, list); } ((list<object>)subclasstoalias.get(subclass).get(0)).add(tuple[i]); ((list<string>)subclasstoalias.get(subclass).get(1)).add(aliasname); } } } grab (nosuchfieldexception e) { throw new hibernateexception( "could not instantiate resultclass: " + resultclass.getname() ); } object[] newtuple = new object[aliases.length - nestedaliases.size()]; string[] newaliases = new string[aliases.length - nestedaliases.size()]; int = 0; (int j = 0; j < aliases.length; j++) { if (!nestedaliases.contains(aliases[j])) { newtuple[i] = tuple[j]; newaliases[i] = aliases[j]; ++i; } } resulttransformer roottransformer = new aliastobeanresulttransformer(resultclass); object root = roottransformer.transformtuple(newtuple, newaliases); (class<?> subclass : subclasstoalias.keyset()) { resulttransformer subclasstransformer = new aliastobeanresulttransformer(subclass); object subobject = subclasstransformer.transformtuple( ((list<object>)subclasstoalias.get(subclass).get(0)).toarray(), ((list<object>)subclasstoalias.get(subclass).get(1)).toarray(new string[0]) ); propertyaccessor accessor = propertyaccessorfactory.getpropertyaccessor("property"); accessor.getsetter(resultclass, (string)subclasstoalias.get(subclass).get(2)).set(root, subobject, null); } homecoming root; } @override public list transformlist(list collection) { homecoming collection; } } java hibernate hql projection resulttransformer
No comments:
Post a Comment