JPA仅创建一次查询

时间:2016-10-06 10:19:03

标签: java spring jpa jdbc jpa-2.0

首先,对不起,如果我问的是显而易见的,或者问题是否从根本上说是愚蠢的。

更多的学术问题需要知道我是否可以创建一个跨越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)上创建查询?我不仅需要知道我正在与哪个数据库进行通信以准备查询?如果没有适当的连接,人们永远不能执行一个?

1 个答案:

答案 0 :(得分:2)

每个Query对象都绑定到特定的EntityManager,不能在另一个EntityManager中重用,就像每个EntityManager绑定到一个JDBC连接一样。

命名查询是一种缓存已编译查询及其有用元数据的方法。通常,当您使用em.createQuery时,它每次都会解析它。它可能会在缓存中保留一些有关它的信息,因为它很可能再次遇到相同的查询,但这不是必需的。

通过调用createStatement(返回Statement),prepareStatement(返回继承前一个的PreparedStatement)或prepareCall(返回)来创建查询在JDBC连接上的CallableStatement继承前两个)。那些Statement对象没有切换到另一个连接的接口。根据驱动程序的不同,它们可以缓存在Java应用程序中或服务器上。 Statement可以在同一个连接上重复使用多次,但不能在其他连接上重复使用。