在WebSphere 7上运行OpenJPA 1.2.3应用程序,由于某些原因,我们无法在那里使用依赖注入实体管理器。因此,我们在提交/回滚事务后手动关闭它们。最近我发现调用EntityManager.close()
需要相当长的时间(约占整个操作的10%,涉及加载~500个实体)。它的作用是分离在事务期间加载的所有实体。
所以实际上有两个问题:
根据要求添加persistence.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="DocumentUnit" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>ru.mypackage.Document</class>
<class>ru.mypackage.DocParam</class>
<class>ru.mypackage.DocParamPK</class>
<!-- Some more classes -->
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
</properties>
</persistence-unit>
</persistence>
答案 0 :(得分:1)
为什么我们一般需要将实体经理上的所有实体分开关闭?是因为JPA必须检查所有实体是否脏了?
根据JPA规范定义行为。有点简短的故事是,当管理实体时,它与给定的EntityManager相关联。如果/当您关闭该EntityManager时,您必须告诉每个管理实体它的管理器现在已关闭。这应该是一个相当轻量级的操作,但我发现在实践中并非总是如此。原因是OpenJPA插入了一个数据结构来跟踪实体在不再被跟踪时的肮脏。这是针对您可能将其中一个分离的实体合并回另一个持久化上下文(EntityManager)的情况进行优化的。
因为在某些情况下实体被加载为只读访问 - 是否有可能以某种方式告诉OpenJPA这些实体不应该更新,并且不需要将它们标记为脏,更新到DB等? / p>
是和否。有一个feature, LiteAutoDetach
that was added in OpenJPA 2.0.0会使分离过程的重量轻得多。缺点是,如果您希望将其中一个分离的实体合并回持久性上下文,您将放弃一些性能/功能。
我建议您分析EntityManager.close()操作以查看大部分时间花在哪里。您可能正在使用导致此性能问题的其他一些OpenJPA功能。
对于grins,您可以使用persistence.xml文件的内容更新帖子吗?