带有参数线程的JPA2 CriteriaQuery是否可以安全地创建查询?

时间:2017-04-06 08:59:51

标签: java multithreading jpa-2.1

我希望可重用CriteriaQuery与此类似:

    CriteriaBuilder b = cb();
    CriteriaQuery<MyClass> query = b.createQuery(MyClass.class);
    Root<MyClass> myClass= query.from(MyClass.class);
    where.add(b.equal(applicant.get(MyClass_.id),          b.parameter(Integer.class, "id")));
    query.where(where.toArray(new Predicate[where.size()]));
    return query;

现在在工作线程池中我想执行以下操作:

TypedQuery<MyClass > query = em.createQuery(myClassCriteria);
query.setParameter("id", id);
MyClass a = query.getSingleResult();
em.detach(a);
return a;

其中myClassCriteria来自上方CriteriaQuery

是一个线程安全的apporach?我怀疑,query上的设置参数可以在内部修改给定的CriteriaQuery,使其无法保护。

我的怀疑来自偶尔应用程序抛出一些SQL错误parameter 2 is not set的情况。我甚至不知道这里的参数2是什么,因为我在查询中只有1个参数,但是这使得我以这种方式重新使用参数化查询可以是非线程安全的。

错误是不可再生的,因此很难确定原因。

我的JPA提供商是Hiberate

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

1 个答案:

答案 0 :(得分:0)

TypedQuery包含参数值而不是CriteriaQuery。它不应该与typedQuery的其他实例共享。我认为它是线程安全的。 (就像命名查询是线程安全的)

检查ID是否始终填充。 还要检查这是否是唯一一个可能导致此错误的查询,或者是否正在执行其他查询(带有两个参数)。