2011-06-17 24 views
35

Tengo una aplicación Java SE basada en CDI maven-built, que tiene un módulo core, y otros módulos.
Core tiene persistence.xml y algunas entidades. Los módulos tienen entidades adicionales.JPA 2.0: Agregar clases de entidad a PersistenceUnit * desde diferentes jar * automáticamente

¿Cómo puedo agregar las entidades al centro de atención de la unidad de persistencia?

He leído el manual de hibernación, http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/configuration.html#setup-configuration-packaging

También he visto estos SO preguntas

Estoy buscando una solución donde Hibernate lo haría escanee para todas las clases cargadas, o, recogería algún archivo de configuración de las otras jarras (como p. ej. CDI lo hace con beans.xml).

Mi aplicación no utiliza Spring. No insisto en la portabilidad. Me quedaré con Hibernate.

  • ¿Existe alguna solución similar?
  • ¿Hay alguna manera de crear una PU a partir de persistence.xml y agregar clases programáticamente?
  • ¿Puedo agregar clases @Entity al EntityManagerFactory después de que se creó?

Actualización: que encontré en org.​hibernate.​ejb.​Ejb3Configuration:

public Ejb3Configuration configure(String persistenceUnitName, Map integration) 

http://docs.jboss.org/hibernate/entitymanager/3.6/javadocs/

+0

Tal vez esto podría ser una solución: http://stackoverflow.com/questions/15026302/multiple-jars-single-persistence-unit-solution –

Respuesta

2

que he experimentado el mismo problema y por desgracia, no existe una solución fácil, que básicamente se parece JPA no fue diseñado para ser utilizado de esta manera. Una de las soluciones es tener solo una persistence.xml por proyecto de nivel superior (aplicación). Es similar a la configuración de log4j. El archivo persistence.xml debe mostrar todas las clases (usando <class>) o, si no es una aplicación Java SE, archivos jar (usando <jar-file>) que la aplicación utiliza. De esta forma puede colocar entidades de múltiples módulos (jarras) en una sola unidad de persistencia. El inconveniente es obvio: tienes que enumerar todo en un archivo.

EDIT: (posiblemente) He encontrado otra solución que utiliza archivos de mapeo XML, echa un vistazo aquí: Multiple jars, single persistence unit solution?

0

duplicado Posible, ver my SO question.

Nos enfrentamos al mismo problema y la única forma que encontramos fue acumular todas las entidades en un persistence.xml para la aplicación final (web).

Al mismo tiempo, definimos archivos persistence.xml separados en nuestros recursos de prueba para que podamos ejecutar pruebas de aceptación por módulo.

10

Hay varias manera de resolverlo:

  1. Como se describe en Do I need <class> elements in persistence.xml?, se puede establecer hibernate.archive.autodetection propiedad y Hibernate debería ser capaz de buscar todas las clases anotadas de ruta de clases. Sin embargo, eso no es compatible con las especificaciones de JPA.

  2. Si está utilizando la primavera, de la primavera 3.1.2 (o probablemente incluso un poco antes), en LocalContainerEntityManagerFactoryBean, puede definir packageToScan que le pedirá LocalContainerEntityManagerFactoryBean para escanear en la ruta de clase para encontrar todas las clases anotadas. Nuevamente, no cumple con la especificación JPA.

  3. Estaba usando Maven como herramientas de desarrollo. Años antes, escribí un pequeño complemento que generará persistence.xml durante el proceso de compilación. El complemento escaneará desde classpath de compilación para descubrir todas las clases anotadas y enumerarlas en el archivo persistence.xml generado. Esto es muy tedioso, pero el resultado es compatible con las especificaciones JPA. Una desventaja (que no se aplica a la mayoría de las personas, creo) es que la búsqueda ocurre en tiempo de compilación, no en tiempo de ejecución. Esto significa que si tiene una aplicación para la que se proporcionan JAR de entidades solo en implementación/tiempo de ejecución pero no en tiempo de compilación, este enfoque no va a funcionar.

+0

Para el punto 3, parece que alguien ha hecho algo similar que es públicamente avaialble: https://github.com/ljnelson/jpa-maven-plugin –

+1

Para el punto 2, necesita deshabilitar la persistenceUnit que normalmente se configura en 'LocalContainerEntityManagerFactoryBean'. Es decir, si se especifica una persistenceUnit, Spring ignorará la configuración 'packageToScan'. –

0

que tienen un problema similar y solved it con SPI Integrator de Hibernate:

@Override 
public void integrate(Configuration configuration, 
    SessionFactoryImplementor sessionFactory, 
    SessionFactoryServiceRegistry serviceRegistry) { 

    configuration.addAnnotatedClass(MyEntity.class); 
    configuration.buildMappings(); 
} 

El integrador se proporciona como Java service.

6

Ejb3Configuration se ha eliminado en 4.3.0. Si no desea crear un integrador de Hibernate, puede usar la propiedad "hibernate.ejb.loaded.classes".

properties.put(
    org.hibernate.jpa.AvailableSettings.LOADED_CLASSES, 
    Arrays.asList(persistentClasses)); 
Persistence.createEntityManagerFactory("persistence-unit", properties); 

Donde persistentClasses contiene una clase [] con las clases de entidad.

+0

La configuración LOADED_CLASSES está marcada como "Sólo para uso interno" y no está definida en el paquete descargado con Maven. – VaclavC

+0

¡Hola, actualmente estoy usando esto para tener un persistence.xml apuntando a varios archivos jar! ¿Alguna idea de por qué fue eliminada? – Mathias

4

Tengo una configuración ligeramente diferente donde estoy colocando persistence.xml en el archivo WAR pero algunas de sus dependencias incluyen @Entity anotado classed para incluir en la unidad de persistencia.

He resuelto mi problema usando Maven un poco como lo describió Adrian Shum en el n. ° 3, pero usando el elemento para incluir los frascos que se analizarán para las anotaciones @Entity.

He añadido una propiedad a my-web/pom.xml para cada dependencia, incluidas las entidades adicionales. Todos mis frascos son parte de una construcción multiproyecto Maven así que para mí parece.

<properties> 
    <common.jar>common-${project.version}.jar</common.jar> 
    <foo.jar>foo-${project.version}.jar</foo.jar> 
</properties> 

que a partir de entonces añadir lo siguiente a la persistence.xml

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.0" ... > 
    <persistence-unit name="primary"> 
     <jta-data-source>java:jboss/datasources/mysource</jta-data-source> 

     <jar-file>lib/${common.jar}</jar-file> 
     <jar-file>lib/${foo.jar}</jar-file> 

     ... 
    </persistence-unit> 
</persistence> 

Por último configuro el experto en recursos-plugin en web/pom.xml para reemplazar los $ expresiones en la persistencia.xml con las propiedades establecidas en el POM

<build> 
    <resources> 
    <resource> 
     <directory>src/main/resources</directory> 
     <filtering>true</filtering> 
     <includes> 
     <include>**/persistence.xml</include> 
     </includes> 
    </resource> 
    <resource> 
     <directory>src/main/resources</directory> 
     <filtering>false</filtering> 
     <excludes> 
     <exclude>**/persistence.xml</exclude> 
     </excludes> 
    </resource> 
    </resources> 
    ... 
</build> 
-4

de APP 2+ esto hace el truco

<jar-file></jar-file> 

escaneado todos los frascos en la guerra de clases @Entity anotados

1

Se puede hacer uso de este concepto : https://wiki.eclipse.org/Packaging_and_Deploying_EclipseLink_JPA_Applications_(ELUG)

<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="mamcaPU" transaction-type="JTA"> 
     <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
     <jta-data-source>mamcaPU</jta-data-source> 
     <mapping-file>/META-INF/common-layer-mappings.xml</mapping-file> 
    </persistence-unit> 
</persistence> 

común de capa-mappings.xml

<entity-mappings> 
    <entity class="vub.be.mamca.entity.Surveyactorgrouptable"></entity> 
    <entity class="vub.be.mamca.entity.Userevaluationelicitationtable"></entity> 
    <entity class="vub.be.mamca.entity.Userevaluationtable"></entity> 
    <entity class="vub.be.mamca.entity.Usertable"></entity> 
    <entity class="vub.be.mamca.entity.Userweightelicitationtable"></entity> 
</entity-mappings> 
Cuestiones relacionadas