如何使用EclipseLink和Spring配置动态编织?

Kay*_* II 10 java spring tomcat jpa eclipselink

如何使用EclipseLink和Spring配置动态编织?现在我正在尝试使用Junit测试,但我后来必须让它与Tomcat一起使用(我的部门已经标准化了10年之久).

我遇到两个主要问题:

1. Spring需要一个加载时间织布工:

例外:

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:181)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
<snip>
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.weaving.AspectJWeavingEnabler#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
<snip>
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
<snip>
Caused by: java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
    at org.springframework.context.weaving.DefaultContextLoadTimeWeaver.setBeanClassLoader(DefaultContextLoadTimeWeaver.java:91)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1437)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1408)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    ... 44 more
Run Code Online (Sandbox Code Playgroud)

我可以通过配置Spring Instrumentation来解决这个问题:

JVM parameter:
-javaagent:/path/to/org.springframework.instrument-3.1.0.M2.jar
Run Code Online (Sandbox Code Playgroud)

2. Eclipselink对Spring Instrumentation不满意:

错误:

(similar error messages repeated many times)

[EL Severe]: 2011-06-20 16:12:57.951--ServerSession(979781372)--Local Exception Stack: 
Exception [EclipseLink-0] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions: 
---------------------------------------------------------

Exception [EclipseLink-60] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The method [_persistence_set_shellType_vh] or [_persistence_get_shellType_vh] is not defined in the object [ps.entity.JudicialArtifactFamily].
Internal Exception: java.lang.NoSuchMethodException: ps.entity.JudicialArtifactFamily._persistence_get_shellType_vh()
Mapping: org.eclipse.persistence.mappings.ManyToOneMapping[shellType]
Descriptor: RelationalDescriptor(ps.entity.JudicialArtifactFamily --> [DatabaseTable(JUDICIAL_ARTIFACT_FAMILY)])

Exception [EclipseLink-218] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: A NullPointerException would have occurred accessing a non-existent weaved _vh_ method [_persistence_get_shellType_vh].  The class was not weaved properly - for EE deployments, check the module order in the application.xml deployment descriptor and verify that the module containing the persistence unit is ahead of any other module that uses it.
Run Code Online (Sandbox Code Playgroud)

试图通过使用EclipseLink weaver解决这个问题:

-javaagent:/dev/tools/javaagents/eclipselink.jar
Run Code Online (Sandbox Code Playgroud)

但是后来我从问题#1得到了同样的例外.

图书馆版本

我在用:

  • Java 1.6.0_24
  • EclipseLink 2.2.0.v20110202-r8913
  • 春季3.1.0 M2

配置文件

这是我的persistence.xml:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             version="2.0"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="eclipseLinkHashPU" transaction-type="RESOURCE_LOCAL">
        <class>ps.entity.Artifact</class>
        <class>ps.entity.JudicialArtifactFamily</class>
        <class>ps.entity.ShellType</class>
        <class>ps.entity.SourceArtifact</class>
        <class>ps.entity.Health</class>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>    
            <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
            <property name="eclipselink.ddl-generation.output-mode" value="database"/>
        </properties>
    </persistence-unit>
</persistence>
Run Code Online (Sandbox Code Playgroud)

这是我的application.xml:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jaxrs="http://cxf.apache.org/schema/jaxrs" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/tx 
           http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://cxf.apache.org/schema/jaxrs
           http://cxf.apache.org/schema/jaxrs.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd          
           http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">

    <context:component-scan base-package="ps">
    </context:component-scan>

    <context:load-time-weaver/>

    <alias alias="entityManagerFactory" name="eclipseLinkEntityManagerFactory"/>

    <bean id="eclipseLinkEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceXmlLocation" value="classpath:eclipselink-persistence.xml" />
        <property name="persistenceUnitName" value="eclipseLinkHashPU" />
        <property name="jpaPropertyMap">
            <map>
                <entry key="eclipselink.logging.level" value="Severe"/>
                <entry key="eclipselink.target-database" value="org.eclipse.persistence.platform.database.oracle.OraclePlatform"/>
                <entry key="javax.persistence.nonJtaDataSource" value-ref="hash1DataSource"/>
                <!-- it's not good that I'm turning weaving off -->
                <!-- <entry key="eclipselink.weaving" value="false"/> -->
            </map>
        </property>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
                <property name="databasePlatform" value="oracle" />
                <property name="database" value="ORACLE" />
                <property name="generateDdl" value="true" />
                <property name="showSql" value="true" />
            </bean>
        </property>
    </bean>

    <!-- datasources, etc -->
</beans>
Run Code Online (Sandbox Code Playgroud)

Jam*_*mes 4

为了与 Spring 一起编织,我相信你需要类似的东西,

<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
    <property name="defaultDataSource" ref="dataSource" />
    <property name="dataSources">
        <map>
            <entry>
                <key>
                    <value>jdbc/__default</value>
                </key>
                <ref bean="dataSource" />
            </entry>
            <entry>
                <key>
                    <value>jdbc/jta</value>
                </key>
                <ref bean="dataSource" />
            </entry>
        </map>
    </property>
    <property name="loadTimeWeaver">
        <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
    </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

这里有一些信息,

http://wiki.eclipse.org/EclipseLink/Examples/JPA/JPASpring

确保在访问 Spring 上下文之前没有访问您的类。

另一种解决方案是使用静态编织。