We are using websphere-liberty:23.0.0.11-kernel-java17-openj9-ubi
with feature
<feature>persistence-3.0</feature>
and we want to use EclipseLink History https://wiki.eclipse.org/EclipseLink/Examples/JPA/History
we add
@Customizer(HistoryCustomizer.class)
to our Entity class but we get code exceptions all the time The question is which artifactId/version should we add to the pom.xml to support EclipseLink with Liberty with persistence 3.0?
I added such depedency
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
<version>3.0.4</version>
<scope>compile</scope>
</dependency>
and my DescriptorCustomizer
import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.history.HistoryPolicy;
public class HistoryCustomizer implements DescriptorCustomizer {
public void customize(ClassDescriptor descriptor) {
HistoryPolicy policy = new HistoryPolicy();
policy.addHistoryTableName("EMPLOYEE_HIST");
policy.addStartFieldName("START_DATE");
policy.addEndFieldName("END_DATE");
descriptor.setHistoryPolicy(policy);
}
}
, but i got error message about ClassCastException
jakarta.persistence.PersistenceException: Exception [EclipseLink-28019] (Eclipse Persistence Services - 3.0.3.v202208190922): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Deployment of PersistenceUnit [jpa-unit] failed. Close all factories for this PersistenceUnit.
Internal Exception: java.lang.ClassCastException: class com.ibm.saas.siusermgr.application.scope.HistoryCustomizer cannot be cast to class org.eclipse.persistence.config.DescriptorCustomizer (com.ibm.saas.siusermgr.application.scope.HistoryCustomizer is in unnamed module of loader com.ibm.ws.classloading.internal.AppClassLoader @2bba175e; org.eclipse.persistence.config.DescriptorCustomizer is in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @3cab2487)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.createDeployFailedPersistenceException(EntityManagerSetupImpl.java:907)
As mentioned in the doc:
By default, applications do not have access to the third-party APIs that are available in Open Liberty
So even though the persistence-3.0
feature documents providing APIs like org.eclipse.persistence.config.DescriptorCustomizer
, (plus HistoryPolicy
and the other EclipseLink classes), these will not be available to your application without one additional piece of server configuration.
Configure a <classloader>
element for your application like:
<application id="testApp" name="testApp" type="war" location="testApp.war">
<classloader apiTypeVisibility="+third-party" />
</application>
There's probably less opportunity for confusion to use a provided
-scope dependency to clearly load these classes from the runtime-provided version of the library rather than packaging it within your application. It's true that the default "parent-first" classloading might make this not really matter, at first. Still, I'd suggest this as a better starting point, unless/until you really need to consider using your own version (beyond the scope of this post). It's also a bit smaller footprint.
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
<version>3.0.4</version>
<scope>provided</scope>
</dependency>