JPA 2.0: Agregar clases de entidad a PersistenceUnit * desde diferentes jar * automáticamente

Tengo una aplicación Java SE basada en CDI maven-built, que tiene un módulo principal y otros módulos.
Core tiene persistence.xml y algunas entidades. Los módulos tienen entidades adicionales.

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

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

También he visto estas preguntas SO

  • ¿Cómo puedo fusionar / extender unidades de persistencia desde diferentes JAR?
  • define clases de entidad jpa fuera de persistence.xml
  • ¿Carga programáticamente las clases de Entity con JPA 2.0?

Estoy buscando una solución donde Hibernate buscará todas las clases cargadas, o, recogería algún archivo de configuración de las otras jarras (como por ejemplo, CDI hace con beans.xml ).

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

  • ¿Hay alguna de esas soluciones?
  • ¿Hay alguna manera de crear una PU desde persistence.xml y agregar clases programáticamente?
  • ¿Puedo agregar clases @Entity a EntityManagerFactory después de que fue creado?

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

 public Ejb3Configuration configure(String persistenceUnitName, Map integration) 

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

Hay varias formas de resolverlo:

  1. Como se describe en ¿Necesito elementos de en persistence.xml? , puede establecer la propiedad hibernate.archive.autodetection e Hibernate debería poder buscar todas las clases anotadas desde classpath. Sin embargo, eso no es compatible con las especificaciones de JPA.

  2. Si está utilizando Spring, desde Spring 3.1.2 (o probablemente incluso un poco antes), en LocalContainerEntityManagerFactoryBean , puede definir packageToScan que pedirá a LocalContainerEntityManagerFactoryBean que explore en classpath para buscar todas las clases anotadas. Nuevamente, no cumple con la especificación JPA.

  3. Estaba usando Maven como herramientas de construcción. Años antes, escribí un pequeño complemento que generará persistence.xml durante el proceso de comstackción. El complemento escaneará desde classpath de comstackció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 comstackció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 comstackción, este enfoque no va a funcionar.

La configuración Ejb3 ha sido eliminada 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 entidades.

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 flasks que se analizarán para las anotaciones @Entity.

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

  common-${project.version}.jar foo-${project.version}.jar  

A continuación agrego lo siguiente a persistence.xml

 < ?xml version="1.0" encoding="UTF-8"?>   java:jboss/datasources/mysource lib/${common.jar} lib/${foo.jar} ...   

Por último, configuro maven-resource-plugin en web / pom.xml para reemplazar las expresiones $ en persistence.xml con las propiedades establecidas en el POM

    src/main/resources true  **/persistence.xml    src/main/resources false  **/persistence.xml    ...  

He experimentado el mismo problema y desafortunadamente no hay una solución fácil, básicamente parece que JPA no fue diseñado para ser usado de esta manera. Una de las soluciones es tener solo un persistence.xml por proyecto de nivel superior (aplicación). Es similar a la configuración de log4j. Persistence.xml tiene que listar todas las clases (usando ) o, si no es una aplicación Java SE, archivos jar (usando ) que son utilizados por la aplicación. 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.

EDITAR: He encontrado (posiblemente) otra solución que utiliza archivos de mapeo XML, échale un vistazo aquí: ¿ Múltiples jarrones, solución de unidad de persistencia única?

Puede utilizar este concepto: https://wiki.eclipse.org/Packaging_and_Deploying_EclipseLink_JPA_Applications_(ELUG)

   org.eclipse.persistence.jpa.PersistenceProvider mamcaPU /META-INF/common-layer-mappings.xml   

common-layer-mappings.xml

        

Posible duplicado, ver mi pregunta ASÍ .

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.

Tengo un problema similar y lo solucioné con el Integrator SPI de Hibernate:

 @Override public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) { configuration.addAnnotatedClass(MyEntity.class); configuration.buildMappings(); } 

El integrador se proporciona como servicio de Java .

para JPA 2+ esto hace el truco

  

escanear todos los flasks en guerra para las clases anotadas @Entity