Hibernate / JPA生成不带别名的子查询查询

时间:2018-11-01 21:22:31

标签: hibernate jpa jpa-2.0

我有下面的此类,它会生成动态的Hibernate / JPA查询(由于参数的动态性质):

      import java.util.ArrayList;
      import java.util.List;
     import java.util.Map;

   import javax.persistence.EntityManager;
   import javax.persistence.PersistenceContext;
   import javax.persistence.Query;

    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Repository;

        import com.charter.egateway.datalayer.model.AccountDatabase;

        @Repository
        public class AccountRepositoryCustomImpl implements AccountRepositoryCustom 
       {

        @PersistenceContext
        private EntityManager em;

        @Value("${recordLimit}")
        private String recordLimit;

        @Override
        public List<AccountDatabase> searchForAccounts(Map<String, Object> map) {

            boolean hasPassedParameters = false;
            List<String> whereClause = new ArrayList<>();

            StringBuilder queryBuilder = new StringBuilder();
            queryBuilder.append("select ad from AccountDatabase ad ");

            for (String key : map.keySet()) {
                if (!key.equals("city") && !key.equalsIgnoreCase("address")
                        && !key.equalsIgnoreCase("billingAccountNumber")) {

                    if (key.equals("accountType")) {
                        whereClause.add(" ad." + key + " = :" + key);
                    } else {
                        whereClause.add(" UPPER(ad." + key + ") LIKE :" + key);

                    }
                    hasPassedParameters = true;
                }
            }

            queryBuilder.append(" where " + StringUtils.join(whereClause, " and "));

            if (map.containsKey("city")) {
                if (hasPassedParameters) {
                    queryBuilder.append(" AND ");
                }
                queryBuilder.append(" (( ad.accountType LIKE :accountType AND UPPER(ad.billingCity) LIKE :billingCity ) OR "
                        + "( ad.accountType LIKE :accountType2 AND UPPER(ad.shippingCity) LIKE :shippingCity )) ");

                hasPassedParameters = true;

            }

            if (map.containsKey("address")) {
                if (hasPassedParameters) {
                    queryBuilder.append(" AND ");
                }
                queryBuilder
                        .append(" (( ad.accountType LIKE :accountType AND UPPER(ad.billingStreet) LIKE :billingStreet ) OR "
                                + "( ad.accountType LIKE :accountType2 AND UPPER(ad.shippingStreet) LIKE :shippingStreet )) ");

                hasPassedParameters = true;

            }

            if (map.containsKey("billingAccountNumber")) {
                if (hasPassedParameters) {
                    queryBuilder.append(" AND ");
                }
                queryBuilder
                        .append(" (( ad.accountType LIKE :accountType AND ad.billingAccountNumber LIKE :billingAccountNumber ) OR "
                                + "( ad.accountType LIKE :accountType2 AND ad.billingAccountNumberForServiceLocation LIKE :billingAccountNumberForServiceLocation )) ");

            }



            Query jpaQuery = em.createQuery(queryBuilder.toString(), AccountDatabase.class);    

            //Query jpaQuery = em.createQuery(queryBuilder.toString(), AccountDatabase.class);

            for (String key : map.keySet()) {
                if (!key.equals("city") && !key.equalsIgnoreCase("address")
                        && !key.equalsIgnoreCase("billingAccountNumber")) {

                    if (key.equals("accountType")) {
                        jpaQuery.setParameter(key, map.get(key));
                    } else {
                        jpaQuery.setParameter(key, "%" + String.valueOf(map.get(key)).toUpperCase() + "%");
                    }
                }
            }

            if (map.containsKey("address")) {
                if (map.containsKey("accountType")) {

                    jpaQuery.setParameter("accountType", map.get("accountType"));
                    jpaQuery.setParameter("accountType2", map.get("accountType"));
                } else {
                    jpaQuery.setParameter("accountType", "Billing Account");
                    jpaQuery.setParameter("accountType2", "Service Location");

                }
                jpaQuery.setParameter("billingStreet", "%" + String.valueOf(map.get("address")).toUpperCase() + "%");
                jpaQuery.setParameter("shippingStreet", "%" + String.valueOf(map.get("address")).toUpperCase() + "%");
            }

            if (map.containsKey("city")) {
                if (map.containsKey("accountType")) {
                    jpaQuery.setParameter("accountType", map.get("accountType"));
                    jpaQuery.setParameter("accountType2", map.get("accountType"));
                } else {
                    jpaQuery.setParameter("accountType", "Billing Account");
                    jpaQuery.setParameter("accountType2", "Service Location");

                }
                jpaQuery.setParameter("billingCity", "%" + String.valueOf(map.get("city")).toUpperCase() + "%");
                jpaQuery.setParameter("shippingCity", "%" + String.valueOf(map.get("city")).toUpperCase() + "%");
            }

            if (map.containsKey("billingAccountNumber")) {
                if (map.containsKey("accountType")) {
                    jpaQuery.setParameter("accountType", map.get("accountType"));
                    jpaQuery.setParameter("accountType2", map.get("accountType"));
                } else {
                    jpaQuery.setParameter("accountType", "Billing Account");
                    jpaQuery.setParameter("accountType2", "Service Location");

                }

                jpaQuery.setParameter("billingAccountNumber", "%" + map.get("billingAccountNumber") + "%");
                jpaQuery.setParameter("billingAccountNumberForServiceLocation",
                        "%" + map.get("billingAccountNumber") + "%");
            }

            int limit = Integer.valueOf(recordLimit);



            //TypedQuery<AccountDatabase> query = em.createQuery(queryBuilder.toString(), AccountDatabase.class);    

            //List<AccountDatabase> list = jpaQuery.getResultList();

            jpaQuery.setMaxResults(limit);
            List<AccountDatabase> list = jpaQuery.getResultList();
            if (list.size() > limit) {
                list = list.subList(0, limit);
            }

            em.close();
            return list;

        }

    }

不使用本机查询怎么办?如何使它起作用?

Table subquery missing an alias.  On line 1, column 734.  [parser-2909810]

BlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablablaBlablabla

1 个答案:

答案 0 :(得分:0)

我最近遇到了这个问题,并将其追溯到休眠状态的this change

要解决,我写下面的自定义方言基本上恢复其变化:

import org.hibernate.dialect.Oracle12cDialect;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.SQL2008StandardLimitHandler;

public class CustomDialect extends Oracle12cDialect {

    @Override
    public LimitHandler getLimitHandler() {
        return SQL2008StandardLimitHandler.INSTANCE;
    }

}

另外,使用的版本5.3.3.Final还应该解决您的问题,因为这是这种变化之前的最后一个版本。如果使用Maven,也应该是这样的:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.3.3.Final</version>
</dependency>

我很好奇,如果要连接到TIBCO /(是思科)的数据虚拟化平台。