首先,对不起,如果我问的是显而易见的,或者问题是否从根本上说是愚蠢的。
更多的学术问题需要知道我是否可以创建一个跨越EntityManager
或独立于createXXXQuery
的JPA查询(命名或其他)。基本上,准备一次运行。我明白我们只能从enitity manager对象的public class MyRepo {
@PersistenceContext
private EntityManager em;
private Query aQueryIntentedtoBePreparedOnlyOnce;
@PostConstruct
public void prepareMyQuery(){
aQueryIntentedtoBePreparedOnlyOnce = em.createQuery("...."); // Query with positional params
}
public void executeMyQuery(){
aQueryIntentedtoBePreparedOnlyOnce.getResultList();
}
}
方法中获取一个Query实例,但是还有另一种方法吗?
这就是我想要做的,
createNamedQuery
这是第一次完美执行。但是,它第二次说'#34;实体经理关闭了。"我理解这是因为EM是事务范围。
这个EM是容器管理的(JTA - Spring),所以我不能在事务中扩展它。并且,使用会话bean不是一种选择。那么,有没有办法只创建一次这个查询?
PS:命名查询和查询缓存在哪里?使用命名查询我似乎每次都会{"date:"2016-09-05T16:15:30.623Z"}
。什么是查询缓存计划有什么好的文档吗?
另外一个问题,为什么只在EM或Connection(JDBC)上创建查询?我不仅需要知道我正在与哪个数据库进行通信以准备查询?如果没有适当的连接,人们永远不能执行一个?
答案 0 :(得分:2)
每个Query对象都绑定到特定的EntityManager,不能在另一个EntityManager中重用,就像每个EntityManager绑定到一个JDBC连接一样。
命名查询是一种缓存已编译查询及其有用元数据的方法。通常,当您使用em.createQuery
时,它每次都会解析它。它可能会在缓存中保留一些有关它的信息,因为它很可能再次遇到相同的查询,但这不是必需的。
通过调用createStatement
(返回Statement
),prepareStatement
(返回继承前一个的PreparedStatement
)或prepareCall
(返回)来创建查询在JDBC连接上的CallableStatement
继承前两个)。那些Statement对象没有切换到另一个连接的接口。根据驱动程序的不同,它们可以缓存在Java应用程序中或服务器上。 Statement可以在同一个连接上重复使用多次,但不能在其他连接上重复使用。