0

I have re-written my entire question with my latest configuration. I have been changing and testing multiple times and still have not found the proper solution.

I am having difficulty enabling load-time-weaving for jpa class enhancement in my project.

I am using Websphere 8.5 which in turn uses openjpa 2.2.2. I have one Ear file with one War and many dependant jars that contain JPA entities and custom named persistence.xml files.

like so:

MyApp.ear
|-- lib ## contains spring files and other shared libraries
|-- utilJars ## contains my custom made utility jars
|   |-- core.jar ## core-persistence.xml
|   |-- core-api.jar ## core entities
|   |-- mod1.jar ## mod1-persistence.xml
|   |-- mod1-api.jar ## mod1 entities
|   `-- control.jar ## depends on all above jars (in **`MANIFEST.MF`**), 
|                      `contains the main application context (`control-context.xml`) config shown below
`-- MyWeb.war

My main context file in control.jar called control-context.xml is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                           http://www.springframework.org/schema/jee http://schema.spring.io/jee/spring-jee-4.0.xsd
                           http://www.springframework.org/schema/tx http://schema.spring.io/tx/spring-tx-4.0.xsd
                           http://www.springframework.org/schema/util http://schema.spring.io/util/spring-util-4.0.xsd
                           http://www.springframework.org/schema/context http://schema.spring.io/context/spring-context-4.0.xsd">

    <!-- The transactions in this app is driven through annotations -->
    <tx:annotation-driven/>
    <context:load-time-weaver />

    <!-- Defining our datasource here enables us to inject a JPA persistence context using spring -->

    <jee:jndi-lookup id="oneDS" jndi-name="jdbc/oneDS" expected-type="javax.sql.DataSource" cache="true"/>
    <jee:jndi-lookup id="twoDS" jndi-name="jdbc/twoDS" expected-type="javax.sql.DataSource" cache="true"/>

    <!-- =================== -->
    <!--      EMF SETUP      -->
    <!-- =================== -->

    <!-- COMMON EMF PROPERTIES -->
    <bean id="baseEMF" abstract="true" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
        <property name="persistenceProvider">
            <bean class="org.apache.openjpa.persistence.PersistenceProviderImpl" />
        </property>
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
        <property name="jpaPropertyMap" ref="jpaPropertiesMap" />
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.OpenJpaDialect" />
        </property>
    </bean>

    <!-- Merging persistence unit combines all *-persistence.xml files from seperate modules by PU name
         e.g. onePU, twoPU etc.. -->
    <bean id="basePum" class="org.springframework.data.jpa.support.MergingPersistenceUnitManager" abstract="true">
        <!-- store all persistence information in the <module-name>-persistence.xmls located under the custom META-INF
             directory for each module-->
        <property name="persistenceXmlLocation" value="classpath*:META-INF/**/*-persistence.xml" />
        <property name="packagesToScan" value="com.example.myapp.**.model" />
    </bean>

    <!-- COMMON JPA VENDOR ADAPTER PROPERTIES -->
    <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
        <property name="database" value="DB2"/>
        <property name="generateDdl" value="false"/>
        <!-- I imagine that this would be turned off in production,
             leaving this here for the time being. -->
        <property name="showSql" value="true"/>
    </bean>

    <!-- COMMON JPA PROPERTIES -->
    <util:map id="jpaPropertiesMap">
        <entry key="openjpa.jdbc.DBDictionary" value="db2" />
        <entry key="openjpa.TransactionMode" value="managed" />
        <entry key="openjpa.ConnectionFactoryMode" value="managed" />
        <entry key="openjpa.DynamicEnhancementAgent" value="true"/>
    </util:map>

    <!-- ONE EMF SETUP -->
    <bean id="oneEMF" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" parent="baseEMF">
        <property name="persistenceUnitName" value="onePU" />
        <property name="persistenceUnitManager">
            <bean class="org.springframework.data.jpa.support.MergingPersistenceUnitManager" parent="basePum">
                <property name="defaultJtaDataSource" ref="oneDS" />
                <property name="defaultPersistenceUnitName" value="onePU" />
            </bean>
        </property>
    </bean>

    <!-- TWO EMF SETUP -->
    <bean id="twoEMF" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" parent="baseEMF">
        <property name="persistenceUnitName" value="twoPU" />
        <property name="persistenceUnitManager">
            <bean class="org.springframework.data.jpa.support.MergingPersistenceUnitManager" parent="basePum">
                <property name="defaultJtaDataSource" ref="twoDS" />
                <property name="defaultPersistenceUnitName" value="twoPU" />
            </bean>
        </property>

    </bean>

    <!-- the default unit of work manager is located at 'java:comp/websphere/UOWManager' -->
    <bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/>

    <!-- Automatically picked up by the spring entity manager factory -->

</beans>

I am using a merging persistence unit manager provided by spring to combine the persistence unit declarations in the custom persistence unit xml's located under META-INF/<module-name>/<module-name>-persistence.xml folder of each jar. e.g. META-INF/core/core-persistence.xml.

here is one such file:

<?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://www.w3.org/2001/XMLSchema-instance http://www.w3.org/2001/XMLSchema-instance
             http://java.sun.com/xml/ns/persistence http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/persistence_2_0.xsd" version="2.0">
    <persistence-unit name="onePU">
        <class>com.example.myapp.core.model.MyEntity</class>
        <class>com.example.myapp.core.model.MyEntityId</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
    </persistence-unit>
</persistence>

My entities all have @Entity and proper @Id tags and what not, They have been working as entities before and I haven't modified them, so I'm sure that my entities are valid.

And now for the QUESTION:

I have a spring rest jpa resource repository set up in my mod1 jar that uses the oneEMF:

<jpa:repositories base-package="com.example.myapp.mod1.model.repositories" entity-manager-factory-ref="oneEMF" />

when i hit the url after the application is deployed and started, I get this message:

Error 500: org.springframework.web.util.NestedServletException: Request processing failed; 
`-- nested exception is org.springframework.orm.jpa.JpaSystemException: No registered metadata for type "class com.example.myapp.core.model.MyEntity". This can happen if this class has not been annotated as a persistent entity or specified in the persistence unit (ex: in the orm.xml). ; 
`-- nested exception is <openjpa-2.2.2-SNAPSHOT-r422266:1462076 nonfatal general error> org.apache.openjpa.persistence.PersistenceException: No registered metadata for type "class com.example.myapp.core.model.MyEntity". This can happen if this class has not been annotated as a persistent entity or specified in the persistence unit (ex: in the orm.xml).

Why are my entities not enhancing at load time?

I have lost many hours attempting to configure this supposedly simple setup, however I am at a loss as to why the enhancement is not occuring for me. any help or even sympathy would be much appreciated.

UPDATE:

placing a dummy persistence.xml in the META-INF directory of my war classes folder has managed to trigger the entity scanning, but from what I've read, I don't need the persistence.xml if I am using packagesToScan with spring. Does this package scanning refer to entities that will be enhanced by the load-time-weaver?

Thank you for your time.

Community
  • 1
  • 1
coderatchet
  • 8,120
  • 17
  • 69
  • 125
  • Please post class com.example.mymodule.model.SomeEntity. Do you include OpenJPA JAR into your app or use the one shipped with WebSphere? Please post your persistence.xml. – Magic Wand Aug 21 '14 at 07:55
  • If I need OpenJPA in the classpath, where would i get it from? I can see the jar in the plugins folder in WebSphere/AppServer/plugins. do I need to manually place that in my ear or shared libraries or is there someway to reference that in a more websphery way? – coderatchet Aug 21 '14 at 23:31
  • You dont need openJPA jars, they are provided with WebSphere, but you need persistence.xml for annotations to be processed by the container. – Gas Aug 22 '14 at 00:20
  • Spring suggests that you can construct a persistence unit without the persistence xml.are you saying that i need a persistence xml anyway? – coderatchet Aug 22 '14 at 00:27
  • If you use LocalContainerEntityManagerFactoryBean with Spring-based scanning, you do not need persistence.xml. Could you add tag into your configuration? – Magic Wand Aug 22 '14 at 08:04
  • Another option to try is to add loadTimeWeaver bean directly into LocalContainerEntityManagerFactoryBean: – Magic Wand Aug 22 '14 at 08:19
  • I already tried the later method, and the former does not work either. – coderatchet Aug 25 '14 at 05:30

0 Answers0