如何解決hibernate duplicate association

我們使用hibernate作爲DAO層時,有時會遇到如下錯誤:

org.hibernate.QueryException: duplicate association path: agent

duplicate association

具體是什麼錯誤呢?

Criteria criteria=this.inspectionOrderDao.createCriteria();
        criteria.createCriteria("agent").add(Restrictions.eq("type", 1));//不報錯

        criteria.createCriteria("agent").add(Restrictions.eq("enable", 1));//報錯:duplicate association

 上面的代碼就會報錯.

實際代碼結構及業務肯定比上述要複雜,

設置條件不在一個方法裏面.

如果出現這種異常就會直接導致接口報錯,導致服務不可用.

如何解決 呢?

實際上我們有辦法判斷 Criteria 中是否已經存在了子查詢路徑:

public static SubCriteriaDto isSubcriteriaContains(Criteria criteria, String associationPath) {
        CriteriaImpl criteria2 = (CriteriaImpl) criteria;
        return isSubcriteriaContains(criteria2, associationPath);
    }

    /***
     * 解決org.hibernate.QueryException: duplicate association path: community
     * @param criteria2
     * @param associationPath
     * @return
     */
    public static SubCriteriaDto isSubcriteriaContains(CriteriaImpl criteria2, String associationPath) {
        Iterator<CriteriaImpl.Subcriteria> subcriteriaIterator = criteria2.iterateSubcriteria();
        SubCriteriaDto subCriteriaDto=new SubCriteriaDto();
        while (subcriteriaIterator.hasNext()) {
            CriteriaImpl.Subcriteria subcriteria = subcriteriaIterator.next();
            String path = subcriteria.getPath();
            System.out.println("path :" + path);
            if (path.equals(associationPath)) {
                subCriteriaDto.setContains(true);
                subCriteriaDto.setSubCriteria(subcriteria);
                return subCriteriaDto;
            }
        }
        return subCriteriaDto;
    }

 

應用:

public void condition(Field field, Object entityProp) {
        Integer id = ReflectHWUtils.getObjectIntValue(entityProp, Constant2.DB_ID);
        if (null == id || id == SystemHWUtil.NEGATIVE_ONE) {
            //解決Caused by: org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of oa.entity.HouseInfo.address
            //沒有執行createAssiate()
            // criteria.createCriteria(key).add(getExample(value, false, isLike));
            String associationPath = field.getName();
            SubCriteriaDto subCriteriaDto=ConditionQueryUtil.isSubcriteriaContains(this.criteria, associationPath);
            if (subCriteriaDto.isContains()) {//已經存在該路徑的子查詢
                subCriteriaDto.getSubCriteria().add(Example.create(entityProp));
            } else {
                this.criteria.createCriteria(associationPath).add(Example.create(entityProp));
            }

        } else {
            eq(field.getName() + ".id", id);
        }
    }

 

附上SubCriteriaDto結構:

package oa.bean;

import org.hibernate.internal.CriteriaImpl;

public class SubCriteriaDto {
    private boolean isContains;
    private CriteriaImpl.Subcriteria subCriteria;

    public boolean isContains() {
        return isContains;
    }

    public SubCriteriaDto setContains(boolean contains) {
        isContains = contains;
        return this;
    }

    public CriteriaImpl.Subcriteria getSubCriteria() {
        return subCriteria;
    }

    public SubCriteriaDto setSubCriteria(CriteriaImpl.Subcriteria subCriteria) {
        this.subCriteria = subCriteria;
        return this;
    }
}

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章