GlassFish 4 / EclipseLink的@ManyToOne关系的延迟加载失败 [英] Lazy loading of @ManyToOne relation fails with GlassFish 4 / EclipseLink

查看:89
本文介绍了GlassFish 4 / EclipseLink的@ManyToOne关系的延迟加载失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

GlassFish 4(实际上是其JPA实现,即EclipseLink)无法从Java EE 7应用程序延迟加载@ManyToOne JPA关系。默认/急切加载是可以的,但懒加载不会。

GlassFish 4 (actually its JPA implementation, i.e. EclipseLink) fails to lazy load a @ManyToOne JPA relation from our Java EE 7 application. Default/eager loading is ok, but not lazy loading.

学生实体中的关系为:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "addr_id")
private Address address;

(简化的)persistence.xml看起来像:

The (simplified) persistence.xml looks like:

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">
    <persistence-unit name="foo-PU" transaction-type="JTA">
        <jta-data-source>jdbc/foo-DS</jta-data-source>
        <class>foo.domain.Student</class>
        <class>foo.domain.Address</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <property name="eclipselink.target-database" value="PostgreSQL"/>
            <property name="eclipselink.logging.level" value="FINE"/>
        </properties>
    </persistence-unit>
</persistence>

该应用程序使用多个API:PrimeFaces,JSF 2.2,CDI 1.1,JPA 2.1。

The application uses several API: PrimeFaces, JSF 2.2, CDI 1.1, JPA 2.1.

还请注意,不是通过注入会话EJB来获得EntityManager,而是使用Persistence.createEntityManagerFactory(...)然后emf.createEntityManager(...)手动创建的。

Also note that the EntityManager are not obtained by injection into session EJB, but manually created using Persistence.createEntityManagerFactory(...) then emf.createEntityManager(...).

错误消息是:

WARNING:   Reverting the lazy setting on the OneToOne or ManyToOne attribute [address] for the entity class [class foo.domain.Student] since weaving was not enabled or did not occur.

我的理解是,由于某种原因,未启用实体的动态编织。对于Java EE应用程序,应按照 http:// wiki的建议进行设置.eclipse.org / EclipseLink / UserGuide / JPA / Advanced_JPA_Development / Performance / Weaving

My understanding is that, for some reason, the dynamic weaving of entities is not enabled. For a Java EE application it should be, as suggested by http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving.

作为记录,如果我们尝试使用以下方法强制进行编织:

For the record, if we try to force the weaving using this:

<property name="eclipselink.weaving" value="true"/>

,那么我们会收到另一条错误消息:

in the persistence.xml, then we get another error message:

SEVERE:   Error Rendering View[/student/studentList.xhtml]
javax.el.ELException: /student/studentList.xhtml @24,81 value="#{studentController.selectedCode}": Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28022] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Value [true] for the property [eclipselink.weaving] is incorrect when global instrumentation is null, value should either be null, false, or static.
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIOutput.getValue(UIOutput.java:174)
at javax.faces.component.UIInput.getValue(UIInput.java:291)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
(...)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)

任何想法如何解决这个延迟加载问题?为什么默认情况下不启用动态编织?

Any idea how to fix this lazy-loading issue? Why is the dynamic weaving not enabled by default ?

谢谢。

推荐答案

如果将 eclipselink.weaving 设置为 true ,则意味着您要动态地编织实体类。为此,您需要使用适当的javaagent运行jvm。首先下载一个代理

If you set eclipselink.weaving to true it means that you want to weave an entity classes dynamically. To make this work you need to run a jvm with a proper javaagent. First download an agent

wget -O /tmp/eclipselink.jar \
https://repo1.maven.org/maven2/org/eclipse/persistence/eclipselink/2.7.7/eclipselink-2.7.7.jar

,然后运行您的应用使用以下代码段

and then run your app using following snippet

java -javaagent:/tmp/eclipselink.jar ....

但是,如果将 eclipselink.weaving 设置为 static ,则您会您要静态编织实体类的jpa。当然,您必须使用此Maven插件来触发挥动动作,例如 https:/ /github.com/craigday/eclipselink-staticweave-maven-plugin

But if you set eclipselink.weaving to static then you inform jpa that you want to weave the entity classes statically. Of course you have to trigger the waving by your own for example using this maven plugin https://github.com/craigday/eclipselink-staticweave-maven-plugin

这篇关于GlassFish 4 / EclipseLink的@ManyToOne关系的延迟加载失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆