我们将jpa与Toplink一起用作实现,并提出了刷新实体列表的问题。
基本上就是这种情况:
private List<Entity> findAll()
{
final String sql = "SELECT e from " + anEntityClass.getSimpleName() + " e";
final Query query = itsManager.createQuery(sql);
List<Entity> result = query.getResultList();
return result;
}
但是如果我们通过外部方式修改数据库,第二次调用findAll()方法将返回过时的信息,因为它重用了缓存中存储的信息。
此问题的一个解决方案是指定
query.setHint("toplink.refresh", "True");
所以我们总是得到刷新的数据。但是我们依赖于Toplink,如果我们需要更换提供商,我们将面临问题。
我知道有一个entityManager.refesh()方法,但我只是将它与entitytManager.find()结合使用才能得到一个实体。
是否有任何标准方法可以获取实体列表的新数据?
答案 0 :(得分:1)
这是与JPA合作的一个令人沮丧的部分,我认为这是我在许多应用程序中遇到的问题。我们建立的实践是实际上只是完全清除会话并重新运行使我们的结果集开始的查询。 refresh()的一个问题是级联。如果你有延迟加载的集合或其他已经被提取到内存中的引用,那么每个项目都会被刷新,这会使整个过程花费很长时间。
但我不得不说,我的务实方面说你不太可能改变你的持久性提供者,如果你有一些适用于TopLink的东西,那么就继续吧。了解如何充分利用您拥有的工具,不要担心“有一天可能”需要切换到Hibernate或其他东西。
答案 1 :(得分:1)
您可以在persistence.xml中设置一个属性,以禁用所有实体或特定实体的缓存。
<persistence-unit name="local" transaction-type="RESOURCE_LOCAL">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<properties>
<property name="toplink.cache.type.default" value="NONE" />
<property name="toplink.cache.type.the.class.package.ClassName" value="NONE" />
</properties>
</persistence-unit>
答案 2 :(得分:0)
我想您可以保留该属性,并在更改持久性提供程序时将其更改为新属性。我认为,如果发生这种变化,这将是你最不重要的问题。
您还可以为每个持久单位设置此类属性。
如果此方案的范围有限(以便您不会在每次查询时最终清除会话),则可以使用EntityManager.clear()