JPQL集合参数 - 与预期类型不匹配

时间:2015-07-01 10:27:51

标签: java spring hibernate jpql

一点上下文:我有一个带有Hibernate的Spring应用程序。

我希望按ID过滤所有位置实体,因此我将一组ID作为参数传递给查询。问题是在query.setParameter("ids", locationIds);行上我收到以下错误:

:Parameter value element [728331] did not match expected type [java.lang.Long (n/a)]

我很困惑,因为我给的集是Long值集。所以我假设在将其作为参数传递时不应该进行明确的转换,对吗?有没有人建议导致错误的是什么?

我检查了其他类似的问题,但我没有找到解决我问题的问题。

@Repository
@Transactional(propagation = Propagation.MANDATORY)
public class LocationDao {

    @PersistenceContext
    private EntityManager em;

    public List<Location> getLocationsByIds(Set<Long> locationIds) {
        if (locationIds == null || locationIds.isEmpty()) {
            return null;
        }
        final TypedQuery<Location> query =
                em.createQuery("FROM Location l WHERE l.id IN :ids", Location.class);
        query.setParameter("ids", locationIds);
        return query.getResultList();
    }
}

@Entity
@Table(name = "location")
public class Location {

    @Id
    private Long id;

    // other fields
}

编辑:Hibernate实体管理器版本:4.3.8.Final

1 个答案:

答案 0 :(得分:1)

发现问题。 locationIds不完全是Set<Long> locationIds,而是Set<BigInteger>

我通过本机查询检索ID,因为我需要在位置执行递归搜索。虽然我将其转换为List<Long>,但它实际上会返回List<BigInteger>。这是代码:

private static final String SQL_FIND_LOCATION_AND_CHILDREN_IDS =
        " WITH RECURSIVE result_table(id) AS ( "
                + "  SELECT  pl.id "
                + "  FROM location AS pl "
                + "  WHERE pl.id = :parentId "
                + "UNION ALL "
                + "  SELECT c.id "
                + "  FROM result_table AS p, location AS c "
                + "  WHERE c.parent = p.id "
                + ") "
                + "SELECT n.id FROM result_table AS n";

@SuppressWarnings("unchecked")
public List<Long> getLocationAndAllChildren(Long parentId) {
    final Query query = em.createNativeQuery(SQL_FIND_LOCATION_AND_CHILDREN_IDS);
    query.setParameter("parentId", parentId);

    return query.getResultList();
}

然后我可以采用BigInteger的long值,因为我确信这些值符合Long的大小。

@SuppressWarnings("unchecked")
public List<Long> getLocationAndAllChildren(Long parentId) {
    final Query query = em.createNativeQuery(SQL_FIND_LOCATION_AND_CHILDREN_IDS);
    query.setParameter("parentId", parentId);

    final List<BigInteger> resultList = query.getResultList();
    final List<Long> result = new ArrayList<Long>();
    for (BigInteger bigIntId : resultList) {
        result.add(bigIntId.longValue());
    }
    return result;
}

感谢大家的回复和抱歉浪费你的时间。