how to write Hibernate Criteria to take nested objects by Projection List?

前端 未结 3 814
名媛妹妹
名媛妹妹 2020-12-30 07:32

I want to take Nested object values in Hibernate Projection List. I having Pojo \'Charge\' and \'Tariff\' class with OneToMany and ManyToOne relations.

My sample cod

3条回答
  •  渐次进展
    2020-12-30 08:20

    The AliasToBeanNestedResultTransformer does not handle Multilevel Nested DTO's. Meaning, you won't be able to do company.employee.location each in its own DTO.

    Here is a Transformer I wrote that handles Multilevel Nested DTOs. You may used it by calling:

    criteria.setResultTransformer( AliasToBeanNestedMultiLevelResultTransformer(mappingBean));

    Hope it helps.

    public class AliasToBeanNestedMultiLevelResultTransformer extends AliasedTupleSubsetResultTransformer {
    
    private static final long serialVersionUID = -8047276133980128266L;
    
    public boolean isTransformedValueATupleElement(String[] aliases, int tupleLength) {
        return false;
    }
    
    private boolean initialized;
    private Class resultClass;
    private Map> clazzMap = new HashMap<>();
    private Map settersMap = new HashMap<>();
    
    public AliasToBeanNestedMultiLevelResultTransformer(Class resultClass) {
        this.resultClass = resultClass;
    }
    
    public Object transformTuple(Object[] tuples, String[] aliases) {
    
        Map nestedObjectsMap = new HashMap<>();
    
        Object result;
        try {
            result = resultClass.newInstance();
    
            if (!initialized){
                initialized = true;
                initialize(aliases);
            }
    
            for (int a=0;a0){
                    String basePath = alias.substring(0, index);
                    baseObject = nestedObjectsMap.get(basePath);
                    if (baseObject == null){
                        baseObject = clazzMap.get(basePath).newInstance();
                        nestedObjectsMap.put(basePath, baseObject);
                    }
                }
    
                settersMap.get(alias).set(baseObject, tuple,null);
    
            }
    
            for (Entry entry:nestedObjectsMap.entrySet()){
                Setter setter = settersMap.get(entry.getKey());
                if (entry.getKey().contains(".")){
    
                    int index = entry.getKey().lastIndexOf(".");
                    String basePath = entry.getKey().substring(0, index);
                    Object obj = nestedObjectsMap.get(basePath);
    
                    setter.set(obj, entry.getValue(), null);
                }
                else{
                    setter.set(result, entry.getValue(), null);
                }
            }
    
        }catch ( InstantiationException | IllegalAccessException e) {
            throw new HibernateException( "Could not instantiate resultclass: " + resultClass.getName() );
        }
    
        return result;
    }
    
    
    private void initialize(String[] aliases) {
    
        PropertyAccessor propertyAccessor = new ChainedPropertyAccessor(
                new PropertyAccessor[] {
                        PropertyAccessorFactory.getPropertyAccessor( resultClass, null ),
                        PropertyAccessorFactory.getPropertyAccessor( "field" )
                }
        );
    
        for (int a=0;a baseClass = resultClass;
    
            if (alias.contains(".")){
    
                String[] split = alias.split("\\.");
    
                StringBuffer res = new StringBuffer();
    
                for (int i=0;i0) res.append(".");
    
                    String item = split[i];
                    res.append(item);
    
                    String resString = res.toString();
    
                    if (i==split.length-1){
                        clazzMap.put(resString,baseClass);
                        settersMap.put(resString, propertyAccessor.getSetter(baseClass, item));
                        break;
                    }
    
                    Class clazz = clazzMap.get(resString);
                    if (clazz==null){
                        clazz = propertyAccessor.getGetter(baseClass,item).getReturnType();
                        settersMap.put(resString, propertyAccessor.getSetter(baseClass, item));
                        clazzMap.put(resString,clazz);
                    }
                    baseClass = clazz;
                }
            }
            else{
                clazzMap.put(alias, resultClass);
                settersMap.put(alias, propertyAccessor.getSetter(resultClass, alias));
            }
    
        }
    
    }
    

    }

提交回复
热议问题