java jpa java-ee persistence glassfish

java - Compartir una unidad de persistencia entre los componentes en un archivo.ear



jpa java-ee (7)

En una aplicación Java EE 6 donde estoy usando .ear packaging, me gustaría crear una unidad de persistencia a la que se pueda acceder desde componentes en diferentes archivos .jar.

Sin embargo, no estoy seguro de cómo definir esta unidad de persistencia. Con la anotación @PersistenceContext, la búsqueda solo tiene éxito si el nombre coincide con una unidad de persistencia definida en el archivo local persistence.xml.

¿Es posible referirse a unidades de persistencia externas?


Aquí están las secciones relevantes de la especificación JPA 2.0:

8.2 Envasado de unidad de persistencia

...

Una unidad de persistencia se define mediante un archivo persistence.xml . El archivo jar o directorio cuyo directorio META-INF contiene el archivo persistence.xml se denomina raíz de la unidad de persistencia. En entornos Java EE, la raíz de una unidad de persistencia debe ser una de las siguientes:

  • un archivo EJB-JAR
  • el directorio WEB-INF / classes de un archivo WAR [80]
  • un archivo jar en el directorio WEB-INF / lib de un archivo WAR
  • un archivo jar en el directorio de la biblioteca EAR
  • un archivo jar de cliente de aplicación

No es necesario que un archivo EJB-JAR o WAR que contiene una unidad de persistencia se empaquete en un EAR a menos que la unidad de persistencia contenga clases de persistencia además de las contenidas dentro de EJB-JAR o WAR. Ver la Sección 8.2.1.6.

NOTA: Java Persistence 1.0 admite el uso de un archivo jar en la raíz del EAR como la raíz de una unidad de persistencia. Este uso ya no es compatible. Las aplicaciones portátiles deberían usar el directorio de la biblioteca EAR para este caso . Ver [9].

Una unidad de persistencia debe tener un nombre. Solo se debe definir una unidad de persistencia de cualquier nombre dentro de un único archivo EJB-JAR, dentro de un solo archivo WAR, dentro de un solo contenedor de aplicaciones, o dentro de un EAR. Consulte la Sección 8.2.2, "Alcance de la unidad de persistencia".

El archivo persistence.xml se puede usar para designar más de una unidad de persistencia dentro del mismo ámbito.

Todas las clases de persistencia definidas a nivel del EAR de Java EE deben ser accesibles para todos los demás componentes de Java EE en la aplicación , es decir, cargados por el cargador de clases de la aplicación, de modo que si dos diferentes componentes Java EE hacen referencia a la misma clase de entidad (que usar diferentes unidades de persistencia), la clase referenciada es la misma clase idéntica.

Y después:

8.2.2 Alcance de la unidad de persistencia

Un jar de cliente de aplicación EJB-JAR, WAR, o EAR puede definir una unidad de persistencia.

Al hacer referencia a una unidad de persistencia que utiliza el elemento de anotación unitName o el elemento de descriptor de despliegue de persistence-unit-name , el alcance de visibilidad de la unidad de persistencia viene determinado por su punto de definición:

  • Una unidad de persistencia que se define en el nivel de un jar EJB-JAR, WAR o cliente de aplicación tiene un alcance para ese EJB-JAR, WAR o jar de aplicación, respectivamente, y es visible para los componentes definidos en ese jar o war.
  • Una unidad de persistencia que se define en el nivel del EAR es generalmente visible para todos los componentes en la aplicación . Sin embargo, si una unidad de persistencia del mismo nombre está definida por un archivo EJB-JAR, WAR o archivo jar de aplicación dentro del EAR, la unidad de persistencia de ese nombre definida al nivel EAR no será visible para los componentes definidos por ese EJB- JAR, WAR o el archivo jar de la aplicación, a menos que la referencia de la unidad de persistencia use la sintaxis # nombre de la unidad de persistencia para especificar un nombre de ruta para desambiguar la referencia. Cuando se utiliza la sintaxis # , el nombre de la ruta es relativo al archivo jar del componente de la aplicación de referencia. Por ejemplo, la sintaxis ../lib/persistenceUnitRoot.jar#myPersistenceUnit refiere a una unidad de persistencia cuyo nombre, como se especifica en el elemento name del archivo persistence.xml , es myPersistenceUnit y para el cual el nombre de ruta relativa de la raíz del la unidad de persistencia es ../lib/persistenceUnitRoot.jar . La sintaxis # se puede usar tanto con el elemento de anotación unitName como con el elemento de descriptor de despliegue de persistence-unit-name unidad de persistencia para hacer referencia a una unidad de persistencia definida en el nivel EAR.

También debe incluir las clases de entidad jar en el manifiesto de pu jar http://wiki.eclipse.org/Packaging_and_Deploying_EclipseLink_JPA_Applications_(ELUG)

Para resumir, debe poder definir sus entidades y la unidad de persistencia en el nivel superior de la EAR y usarlas de los otros módulos.

Simplemente no estoy seguro de entender lo que probaste y qué problema (s) enfrentaste.


Ejemplo de diseño de EAR de trabajo para Glassfish:

EAR + |- lib + | |- core-module.jar | /- persistence-module.jar + | /- META-INF + | /- persistence.xml |- ejb1-module.jar /- ejb2-module.jar

Los módulos EJB pueden ser archivos jar o directorios descompuestos.

En este caso, su persistence.xml puede ser como:

<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> <persistence-unit name="my-persistence-unit"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>MyDataSource</jta-data-source> <!-- Note: it''s relative to `persistence-module.jar` file location in EAR --> <jar-file>../ejb1-module.jar</jar-file> <jar-file>../ejb2-module.jar</jar-file> <properties> <property name="hibernate.current_session_context_class" value="jta"/> <property name="hibernate.id.new_generator_mappings" value="true"/> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.format_sql" value="true"/> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties> </persistence-unit> </persistence>

ejb1-module-1.0-SNAPSHOT.jar actualizar las referencias <jar-file> si usa el control de versiones del módulo (ej. ejb1-module-1.0-SNAPSHOT.jar ).

Los objetos abstractos con la anotación @MappedSuperclass y la inyección de EntityManager se pueden colocar en cualquier jar externo. Este jar no necesita ser mencionado en persistence.xml . Por ejemplo, puede crear core-module.jar con PersistableEntity.java :

public class PersistableEntity { @Id @GeneratedValue private Long id; public Long getId() { return id; } public Integer getVersion() { return version; } }

Y PersistableEntityManager.java :

public class PersistableEntityManager<T extends PersistableEntity> { @PersistenceContext protected EntityManager em; }

Este core-module.jar podría ser utilizado por todos sus proyectos con diferentes unidades de persistencia. Simplemente heredas tus Entidades y EJB y evitas el texto repetitivo. Mira el ejemplo de bilionix-core en github .


El problema se puede resolver colocando un persistence.xml en un archivo jar que se encuentra en el directorio lib de ear''s.

Persistence.xml debe contener los archivos jar que incluyen las entidades. Tuve que dar la ruta relativa a los archivos jar. Mi oreja estructura irectory

|-ear-- |-lib--|... some libs ... | |--my-persistence-xml.jar |-ejb-with-entities1.jar |-ejb-with-entities2.jar

Mi persistence.xml para jboss 7.1.1

<persistence-unit name="my-pu" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:jboss/datasources/mypu</jta-data-source> <jar-file>../ejb-with-entities1.jar</jar-file> <jar-file>../ejb-with-entities1.jar</jar-file> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/> <property name="hibernate.hbm2ddl.auto" value="create-drop"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.format_sql" value="true" /> </properties> </persistence-unit>

Espero que esto ayude


Esto es lo que hice.

1) Empaquetar los archivos de configuración de persistencia en un archivo jar. El archivo jar contendrá:

  • META-INF / persistence.xml (y orm.xml si usa uno)
  • Cree una carpeta "lib" en el proyecto EAR y coloque el contenedor allí

2) Empaquetar las clases de entidades asociadas en otro jar:

  • Coloque este archivo jar en su carpeta de dominio / lib de GlassFish (o en cualquier otra carpeta de lib igual en otros servidores)
  • Inicialmente incluí el archivo jar en la carpeta "lib" de EAR pero no encontré clases
  • Si alguien conoce una mejor manera de manejar esto, por favor explique

El Contexto de persistencia debería estar ahora accesible para todas las aplicaciones EJB y Web incluidas en su aplicación empresarial.


Prueba con esto:

  1. Configure el archivo EAR application.xml de esta manera:

    http://xmlns.jcp.org/xml/ns/javaee/application_7.xsd "version =" 7 "> YourEEApplication

    <initialize-in-order>true</initialize-in-order> <!-- This is the most important thing --> <module> <ejb>YourEJBModule1.jar</ejb> </module> <module> <ejb>YourEJBModule2.jar</ejb> </module> ...... <module> <ejb>YourEJBModuleX.jar</ejb> </module> <module> <web> <web-uri>YourWebModule.war</web-uri> <context-root>YourWebModule</context-root> </web> </module>

  2. En sus proyectos EJB YourEJBModule1, YourEJBModule2 ... y YourEJBModuleX:

Inyectar contexto de persistencia sin la propiedad unitName:

@PersistenceContext(type=PersistenceContextType.TRANSACTION) private EntityManager em; // get & set

  1. Para cada archivo EJB persistence.xml file:

YourEJBModule1:

<?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="PersistenceUnit1" transaction-type="JTA"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <jta-data-source>jdbc/YourDataSource</jta-data-source> <class>com.example.Foo1</class> <!-- Other properties --> </persistence-unit> </persistence>

YourEJBModule2:

<?xml version="1.0" encoding="UTF-8"?> ... <persistence-unit name="PersistenceUnit2" transaction-type="JTA"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <jta-data-source>jdbc/YourDataSource</jta-data-source> <jar-file>YourEJBModule1.jar</jar-file> <class>com.example.Foo2</class> <!-- Other properties --> </persistence-unit> ...

YourEJBModuleX:

<?xml version="1.0" encoding="UTF-8"?> ... <persistence-unit name="PersistenceUnitX" transaction-type="JTA"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <jta-data-source>jdbc/YourDataSource</jta-data-source> <jar-file>YourEJBModule1.jar</jar-file> <jar-file>YourEJBModule2.jar</jar-file> ...... <class>com.example.FooX</class> <!-- Other properties --> </persistence-unit> ...

En la base de datos puede existir varios esquemas, uno por módulo EJB, acceder a ellos a través de jta-data-source

(Desplegado en Glassfish 4)


Quería lograr el módulo EJB de persistencia compartida sin proyecto EAR.

Esto es posible por

  1. mover todas las entidades persistentes para separar el proyecto EJB (no mover persistance.xml a un nuevo proyecto, solo se necesitan clases)
  2. compilando este proyecto EJB
  3. enviar proyecto al servidor GlassFish usando

scpAsSudo ~/NetbeansProjects/UnifyEntities/dist/UnifyEntities.jar [email protected]:/opt/glassfish3/domains/domain1/lib/ext

¡Que te diviertas!


Todo lo que necesita

EAR + |- META-INF + | - persistence.xml |- ejb1-module.jar |- ejb2-module.jar <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> <persistence-unit name="my-persistence-unit"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>MyDataSource</jta-data-source> <!-- Note: it''s relative to `persistence-module.jar` file location in EAR --> <jar-file>../ejb1-module.jar</jar-file> <jar-file>../ejb2-module.jar</jar-file> <properties> ... </properties> </persistence-unit> </persistence>