Wildfly por defecto utiliza la implementación de JPA llamada Hibernate, normalmente esta funciona sin ningún problema. En mi experiencia normalmente evito tener que cambiar la implementación de JPA del servidor Java EE donde voy a correr la aplicación o empaquetar dentro de la aplicación otra versión.

Sin embargo, se presentan ocasiones donde se requiere alguna funcionalidad específica de otra implementación de JPA diferente a la del servidor Java EE. O en mi caso, desarrollar una aplicación que va a ejecutarse en un Weblogic 12c (12.2.1.3) y no me gusta usar Weblogic para desarrollar.

En teoría, como se utiliza el estándar Java EE, debería correr igual en Wildfly que en Weblogic, y así fue, excepto por la implementación de JPA que en algunos casos tiene diferencias en los mapeos de tipo de dato. Por ejemplo, en Hibernate uno de los querys que tengo regresa un tipo de dato Long pero EclipseLink un Integer, o en otro Hibernate regresa un BigDecimal y EclipseLink un Long. Por esta razón opté por utilizar exactamente la misma implementación del servidor de aplicaciones destino.

Configuración del Wildfly

Wildfly ya tiene una prevista para utilizar diferentes implementaciones de JPA, esto se puede ver en el código fuente del Wildfly en GitHub.

Esta configuración se hace por medio de módulos, en este caso para EclipseLink existe el módulo org.eclipse.persistence:main que se encuentra en la ruta $WILDFLY_HOME/modules/system/layers/base/org/eclipse/persistence/main.

Dentro de la ruta del módulo hay que agregar el JAR de EclipseLink que se desea utilizar, en mi caso quería que fuera la misma versión del Weblogic 12c (12.2.1.3) por lo que lo obtuve de la ruta $WL_HOME/oracle_common/modules/oracle.toplink/eclipselink.jar.

Al ver el contenido del módulo quedaría así:

.
├── eclipselink.jar
├── jipijapa-eclipselink-10.1.0.Final.jar
└── module.xml

0 directories, 3 files

Se debe editar el archivo module.xml para indicarle el JAR que debe agregar, el module.xml debería quedar así:

<!-- Represents the EclipseLink module  -->
<module xmlns="urn:jboss:module:1.3" name="org.eclipse.persistence">
    <properties>
        <property name="jboss.api" value="private"/>
    </properties>

    <resources>
        <resource-root path="jipijapa-eclipselink-10.1.0.Final.jar"/>
        <resource-root path="eclipselink.jar">
            <filter>
                <exclude path="javax/**" />
            </filter>
	     </resource-root>
    </resources>

    <dependencies>
        <module name="asm.asm"/>
        <module name="javax.api"/>
        <module name="javax.annotation.api"/>
        <module name="javax.enterprise.api"/>
        <module name="javax.persistence.api"/>
        <module name="javax.transaction.api"/>
        <module name="javax.validation.api"/>
        <module name="javax.xml.bind.api"/>
        <module name="javax.ws.rs.api"/>
        <module name="org.antlr"/>
        <module name="org.dom4j"/>
        <module name="org.javassist"/>
        <module name="org.jboss.as.jpa.spi"/>
        <module name="org.jboss.logging"/>
        <module name="org.jboss.vfs"/>
    </dependencies>
</module>

Luego se debe agregar un system-property, esto se puede hacer con el jboss-cli o directamente editando el archivo XML de configuración. En mi caso el archivo de configuración que utilizo es standalone.xml, dentro de este se debe buscar el elemento <system-properties> para agregar la propiedad, si el elemento no existe se puede crear manualmente debajo del elemento <extensions>. A continuación un ejemplo de como quedaría el elemento <system-properties>:

<system-properties>
    <property name="eclipselink.archive.factory" value="org.jipijapa.eclipselink.JBossArchiveFactoryImpl"/>
</system-properties>

Configuración de la aplicación

Dentro del POM, solamente se requieren 3 dependencias que serían:

<dependencies>
	<dependency>
		<groupId>javax</groupId>
		<artifactId>javaee-api</artifactId>
		<version>7.0</version>
		<scope>provided</scope>
	</dependency>

	<!-- EclipseLink -->
	<dependency>
		<groupId>org.eclipse.persistence</groupId>
		<artifactId>eclipselink</artifactId>
		<version>2.6.5</version>
		<scope>provided</scope>
	</dependency>

	<dependency>
		<groupId>org.eclipse.persistence</groupId>
		<artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
		<version>2.6.5</version>
		<scope>provided</scope>
	</dependency>
</dependencies>

En mi caso la versión del EclipseLink es 2.6.5, sería utilizar la misma versión del JAR que se agregó en el módulo.

En el archivo persistence.xml se debe colocar el <provider>, quedaría similar a este:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" 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">
  <persistence-unit name="appPU" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/appDS</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <properties>
    	<!-- ... -->
    </properties>
  </persistence-unit>
</persistence>

Autor

Marvin Monge

Senior Java Developer / SysAdmin

  • Oracle Certified Expert, Java EE6 Java Persistence API Developer.
  • Oracle Certified Professional, Java SE 7 Programmer.
  • Oracle Linux Certified Implementation Specialist.
  • Oracle WebLogic Server 12c Certified Implementation Specialist.
  • Red Hat Delivery Specialist - Middleware Integration Services.

Flecha Roja Technologies, 2017.