Trouble with Aspectj load-time-weaving when using EclipseLink JPA in Spring dm Server 1.x - jpa

I am attempting to get EclipseLink JPA working inside the Spring dm Server OSGi environment.
Relevant frameworks and libraries downloaded from the Spring Enterprise Bundle Repository include:
dm Server 1.0.2.SR02
AspectJ Runtime 1.6.3
AspectJ Weaver 1.6.3
Spring Framework 2.5.6.A
Eclipse Persistence 1.1.0
Javax Persistence API 1.99.0
I followed the same structure as presented in the PetClinic-1.5.0 example for setting up EclipseLink JPA. Everything works until lazy-fetching is enabled (which requires proxied objects).
Once lazy-fetching is enabled, the following error suggests that load-time-weaving is not working correctly.
---- (truncated for readability)
Exception [EclipseLink-60] (Eclipse Persistence Services - 1.1.0.r3634): org.eclipse.persistence.exceptions.DescriptorExcep tion
Exception Description: The method [_persistence_setcustomer_vh] or [_persistence_getcustomer_vh] is not defined in the object [net.fractech.fds.backoffice.Job].
Internal Exception: java.lang.NoSuchMethodException: net.fractech.fds.backoffice.Job._persistence_getcu stomer_vh()
Mapping: org.eclipse.persistence.mappings.OneToOneMapping[customer]
Descriptor: RelationalDescriptor(net.fractech.fds.backoffice.J ob --> [DatabaseTable(JOBS)])
This shows that the _persistence_getcustomer_vh() and _persistence_setcustomer_vh() methods were not automatically weaved into the Job domain object.
Questions
1.) How do I determine if load-time-weaving is actually working; moreover, how do I log which load time weaving agent and weaver was started? How do I pass switches to this weaver to have it output debugging information?
I assume I started load-time-weaving with <context:load-time-weaver aspectj-weaving="on" />
2.) Many searches have revealed that I do not need to pass the -javaagent parameter to the jvm when using dm Server. Is this correct?
3.) I have assured that my domain objects in another bundle have access to the eclipse persistence classes by asserting com.springsource.org.eclipse.persistence;version="[1.1.0,1.1.0]";import-scope:=application in my eclipselink bundle and including all application bundles within a PAR. Are there any other configurations needed to enable EclipseLink JPA in Spring dm Server?

I had similar problems. First try setting eclipselink.weaving.lazy=false, or eclipselink.weaving=false if that doesn't work. I had to set the latter.
If you would like to refer to the setup I am using to see if it applies to you, I have a post about it on my site.

It is better to use Equinox Waving Springwaver
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
...
<property name="loadTimeWeaver">
<bean class="org.eclipse.equinox.weaving.springweaver.EquinoxAspectsLoadTimeWeaver"/>
</property>
</bean>
You don't need to use -javaagent option then.
You can find working examples with JPA and EclipseLink here http://code.google.com/p/springdm-in-action/ (see Chapter 7).

I have tried to use EquinoxAspectsLoadTimeWeaver into JPa context (with EclipseLink) but it doen't transform the model classes if your EquinoxAspectsLoadTimeWeaver bean declaration is not done into the same bundle than Model bundle.
EquinoxAspectsLoadTimeWeaver transform class ONLY for the classes stored into the bundle wich declare EquinoxAspectsLoadTimeWeaver.
I have tried the sample http://code.google.com/p/springdm-in-action/ (see Chapter 7) (thank for this sample Lukasz). The declaration of EquinoxAspectsLoadTimeWeaver avoid having the error
Caused by: java.lang.IllegalStateException: Cannot apply class transformer without LoadTimeWeaver specified
But Model classes are not transformed (woven). Weaving into EclipseLink manage for instance lazy mode. For instance if you set into the sample model Contact lazy mode like this :
public class Contact {
...
#Column(name="last_name")
#Basic(fetch=FetchType.LAZY)
private String lastName;
you will notice that lazy loading is not applied because Model Contact class is not wowen.
Regards Angelo

Related

Websphere 9.0.0.7 - Cluster Loading Wrong JPA Specification

Having a very frustrating problem right now that I've exhausted all other avenues of research on. In short, we have a certain vendor application that runs on Websphere 9 and requires JPA 2.0 specification for java persistence.
The issue is, despite setting the JPA specification level to 2.0 in the administrative console, as well as setting it via wsadmin command directly, the cluster continues to load JPA 2.1 and ultimately causing big errors when the application runs.
We see it in the startup logs at:
00000001 SharedJPAComp I CWWJP0048I: Initialized the JPA service for
the JPA 2.1 specification level.
Seen in verbose class loading at:
class load: com.ibm.ws.jpa.runtime.JPA21Runtime from:
file:/opt/app/WebSphere90/AppServer_x64/plugins/com.ibm.ws.jpa.container21.jar
And seen in System.Out logs during the actual exception :
0000017c BusinessExcep E CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "insert" on bean
"BeanId([app name redacted], null)". Exception data:
java.lang.AbstractMethodError:
javax/persistence/EntityManagerFactory.createEntityManager(Ljavax/persistence/SynchronizationType;Ljava/util/Map;)Ljavax/persistence/EntityManager;
at
com.ibm.ws.jpa.runtime.JPA21Runtime.createEntityManagerInstance(JPA21Runtime.java:165)
Actual correct setting shown here
Websphere Java Persistence Settings
Has anyone encountered this kind of issue? Research so far has found nothing. Running on Websphere fixpack 9.0.0.7

OSGI Bundle implementing JPA Using DataNucleus 4.0.0 Release

I am trying to implement JPA using DataNucleus in an OSGI Environment (Apache ServiceMix). I am following the guide mentioned here - http://www.datanucleus.org/products/datanucleus/jpa/osgi.html (Section under Name "JPA and OSGi")
As per the documentation here I am using the DataNucleus JPA jar. So I have Deployed this Jar on ServiceMix as follows -
osgi:install mvn:org.datanucleus/datanucleus-jpa/2.1.7
osgi:start bundleId
As this jar export the persistence provider,I have correctly changed the provider in my persistence.xml file to be org.datanucleus.jpa.PersistenceProviderImpl (which is exported by the above bundle) rather than usual org.datanucleus.api.jpa.PersistenceProviderImpl which is in a normal J2EE JPA APP.
I also have the DataNucleus Core Bundle running on my ServiceMix, which was installed on my ServiceMix using the following -
osgi:install mvn:org.datanucleus/datanucleus-core/4.0.0-release
osgi:start bundleId
Please Note: I donot have the datanucleus-api-jpa bundle running on my ServiceMix, as per the documentation, the datanucleus-jpa bundle would export the necessary classes and hence datanucleus-api-jpa bundle would not be required.
At runtime, I am getting the following error Caused by: java.lang.ClassNotFoundException: org.datanucleus.PersistenceConfiguration not found by org.datanucleus.jpa [261]
What I have noticed is that the DataNucleus Core version 4.0.0-release does not have this class, but this class exists in all previous releases (3.2.15).
I cannot deploy DataNucleus Core Version 3.2.XX onto my ServiceMix, because I have other bundles using DataNucleus Core 4.0.0-release and having both is not an option because of Singleton Creation problems.
Please let me know, if you need me to post my code, I will do so.
Please help
Cheers,
Abhijit
In conclusion, you are using incorrect/invalid jars. "datanucleus-jpa" was removed back in v2 of DataNucleus. All recent versions using "datanucleus-api-jpa" (or "datanucleus-api-jdo" if using JDO). A simple download of the DataNucleus zip file for 4.0.x would show this very clearly.

STS reports error in bean config for java.sql.Date property

I have a bean class with a property setter like this:
public void setDueDate(java.sql.Date dueDate)
I also have an instance of this bean configured in XML like this:
<property name="dueDate">
<bean class="java.sql.Date"/>
</property>
STS marks that config with an error:
No constructor with 0 arguments defined in class 'java.sql.Date'
Well, that's true, java.sql.Date has no no-arg constructor. But this app works fine so obviously Spring is smart enough to create a Date instance without a constructor. Question is, why is the STS editor/builder complaining, and is it possible to convince it that this is not an error or warning?
At this time, I can only see 3 situations where the code "would work", in the order of their likeliness to happen:
the parent bean where the property is injected is defined with scope="prototype" or lazy-init="true" and is not accessed at all
the runtime classpath contains an implementation of java.sql.Dateshadowing the original
that particular context xml is not used in the application
Otherwise, Spring should issue a nice:
Could not instantiate bean class [java.sql.Date]: No default constructor found; nested exception is java.lang.NoSuchMethodException: java.sql.Date.<init>()
In case the code works, but STS reports an wrong error, please file a bug against STS at https://issuetracker.springsource.com/browse/STS (as mentioned above).
In the meantime you can workaround this issue by disabling the validation via the Spring preferences for the project. Just go to preferences of the project -> Spring, then the "Project Validators" tab, and deactivate the validation that is responsible for the wrong error report.

How to use JPA annotations in ormlite?

I would like to use JPA annotations in ormlite. These annotations (like #Entity or #Id) belong to the javax.persistence package which is apparently not provided with ormlite. I could not get JPA annotations resolved, whereas ormlite specific annotations (like #DatabaseTable) are ok. Do I need to download a third party jar in order to get JPA annotations working in ormlite ?
I need to work with ormlite + JPA only.
When having a look at http://ormlite.com/javadoc/ormlite-core/index-all.html we can see that there are no JPA annotations documented nor available, although they are described in the user manual.
Thanks a lot in advance !!!
javax.persistence is available in a jar from the central maven repository (for example). It contains all annotations as well as all of the other JPA stuff that ORMLite ignores.
CMobileCom JPA is a new implementation of JPA specification for both Java JDBC and Android. It is light-weight, about 380K. You can add the following gradle dependencies:
Android:
dependencies {
implementation("com.cmobilecom:cmobilecom-jpa-android:${version}#aar") {
transitive = true
}
annotationProcessor "com.cmobilecom:cmobilecom-jpa-processor:$version"
}
Java JDBC:
dependencies {
implementation "com.cmobilecom:cmobilecom-jpa-jdbc:$version"
// annotation processor: generate static metamodel
compileOnly "com.cmobilecom:cmobilecom-jpa-processor:$version"
}
JPA annotations are supported, so you do not need to add another jar to resolve JPA annotations in your code.
See Developer Guide:
https://cmobilecom.com/docs/jpa/latest/devguide/index.html
Disclaimer: I am a developer of CMobileCom JPA.

websphere 7 and (application based) open-jpa 2

I want to not use the built in Websphere 7 jpa plugin, instead use an application WEB-INF/lib/open-jpa 2 and a proprietary persistence provider. I cannot install the OSGI and JPA 2 feature pack for Websphere.
Originally, I was getting a sax parse error simply trying to load the persistence.xml (version="2" not supported). The error was thrown by a class in open-jpa 1.2.3. When I run websphere/appserver/bin/wsjpaversion.bat, the open-jpa 1.2.3 jar is displayed. By default it overrides the open-jpa 2 jar in the app. I created a shared library containing the open-jpa 2 jar with this config option checked: 'Use an isolated class loader for this shared library'. I set my application classloader to load parent last and assigned it the new shared library resource. The 'version 2' error is gone, but there is another problem. When I try to initialize an EntityManager I get an error:
Caused by: javax.persistence.PersistenceException: Failed to load provider from META-INF/services
at javax.persistence.spi.PersistenceProviderResolverHolder$DefaultPersistenceProviderResolver.getPersistenceProviders(PersistenceProviderResolverHolder.java:121)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:91)
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
... 2 more
Caused by: java.lang.ClassCastException: com.ibm.websphere.persistence.PersistenceProviderImpl incompatible with javax.persistence.spi.PersistenceProvider
at javax.persistence.spi.PersistenceProviderResolverHolder$DefaultPersistenceProviderResolver.getPersistenceProviders(PersistenceProviderResolverHolder.java:110)
... 11 more
One more detail: inside the persistence.xml, the provider element is set to the proprietary PersistenceProviderImpl not the default Websphere persistence provider. So where is this websphere default coming from and how do I prevent it? (another important note: when I remove persistence.xml completely, I get the same error)
Thank you
Without installing the feature pack, you're fighting a losing battle. While it is possible to plug in your own JPA implementation, it is not possible to do that with JPA API — so WAS 7 ties you to the 1.0 version of JPA (see, for example, here how this is done — no class loader policy juggling will change that, though it seems tempting at first).