【问题标题】:JPA Generic DAOJPA 通用 DAO
【发布时间】:2015-08-08 15:41:45
【问题描述】:

我正在尝试使用 JPA 实现一个通用 DAO,但我遇到了这个方法的问题:

public List<T> findAllByProperties( Map<String, Object> properties )
{
    CriteriaQuery<T> queryByProperties = createQueryByProperties( properties );
    TypedQuery<T> query = em.createQuery( queryByProperties );
    return query.getResultList(); //(<== this line triggers the error)
}

private CriteriaQuery<T> createQueryByProperties( Map<String, Object> properties )
{
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<T> cq = cb.createQuery( entityClass );
    Root<T> root = cq.from( entityClass );
    Set<Entry<String, Object>> entrySet = properties.entrySet();
    List<Predicate> predicateList = new ArrayList<Predicate>();
    for ( Entry<String, Object> entry : entrySet )
    {
        String key = entry.getKey();
        Object value = entry.getValue();
        Predicate equal = cb.equal( root.get( key ), value );
        predicateList.add( equal );
    }
    cq = cq.where( cb.and( predicateList.toArray( new Predicate[ predicateList.size() ] ) ) );
    return cq;
}

查询似乎没问题:

System.out.println( cq.toString() );

但我得到了这个堆栈跟踪:

Caused by: javax.ejb.EJBException: See nested exception; nested exception is: <openjpa-2.0.0-r422266:935683 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: The specified parameter of type "class [Ljava.lang.Object;" is not a valid query parameter.
    Caused by: <openjpa-2.0.0-r422266:935683 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: The specified parameter of type "class [Ljava.lang.Object;" is not a valid query parameter.
    at org.apache.openjpa.jdbc.sql.DBDictionary.setUnknown(DBDictionary.java:1418)
    at org.apache.openjpa.jdbc.sql.SQLBuffer.setParameters(SQLBuffer.java:644)
    at org.apache.openjpa.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:553)
    at org.apache.openjpa.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:529)
    at org.apache.openjpa.jdbc.sql.SelectImpl.prepareStatement(SelectImpl.java:451)
    at org.apache.openjpa.jdbc.sql.SelectImpl.execute(SelectImpl.java:392)
    at com.ibm.ws.persistence.jdbc.sql.SelectImpl.execute(SelectImpl.java:80)
    at org.apache.openjpa.jdbc.sql.SelectImpl.execute(SelectImpl.java:363)
    at org.apache.openjpa.jdbc.sql.LogicalUnion$UnionSelect.execute(LogicalUnion.java:427)
    at org.apache.openjpa.jdbc.sql.LogicalUnion.execute(LogicalUnion.java:230)
    at org.apache.openjpa.jdbc.sql.LogicalUnion.execute(LogicalUnion.java:220)
    at org.apache.openjpa.jdbc.kernel.SelectResultObjectProvider.open(SelectResultObjectProvider.java:94)
    at org.apache.openjpa.kernel.QueryImpl$PackingResultObjectProvider.open(QueryImpl.java:2068)
    at org.apache.openjpa.lib.rop.EagerResultList.<init>(EagerResultList.java:34)
    at org.apache.openjpa.kernel.QueryImpl.toResult(QueryImpl.java:1246)
    at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:1005)
    at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:861)
    at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:792)
    at org.apache.openjpa.kernel.DelegatingQuery.execute(DelegatingQuery.java:542)
    at org.apache.openjpa.persistence.QueryImpl.execute(QueryImpl.java:288)
    at org.apache.openjpa.persistence.QueryImpl.getResultList(QueryImpl.java:302)
    at cl.site.project.ejb.util.dao.GenericDAO.findAllByProperties(GenericDAO.java:145)

希望有人能帮助我。

【问题讨论】:

    标签: java jpa dao genericdao


    【解决方案1】:

    我找到了解决方法。 见 cmets。

    public List<T> findAllByProperties( Map<String, Object> properties )
    {
        CriteriaQuery<T> queryByProperties = createQueryByProperties( properties );
        TypedQuery<T> query = em.createQuery( queryByProperties );
        // ADDING THIS
        Set<String> keySet = properties.keySet();
        for ( String key : keySet )
        {
            Object value = properties.get( key );
            query.setParameter( key, value );
        }
        //  
        return query.getResultList();
    }
    
    private CriteriaQuery<T> createQueryByProperties( Map<String, Object> properties )
    {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<T> cq = cb.createQuery( entityClass );
        Root<T> root = cq.from( entityClass );
        Set<Entry<String, Object>> entrySet = properties.entrySet();
        List<Predicate> predicateList = new ArrayList<Predicate>();
        for ( Entry<String, Object> entry : entrySet )
        {
            String key = entry.getKey();
            Object value = entry.getValue();
            ParameterExpression<?> val = cb.parameter( value.getClass(), key ); // <-- Adding this line
            Predicate equal = cb.equal( root.get( key ), val ); // <-- And using val instead of value
            predicateList.add( equal );
        }
        cq = cq.where( cb.and( predicateList.toArray( new Predicate[ predicateList.size() ] ) ) );
        return cq;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-06-19
      • 2012-02-21
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 2011-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多