Ampliación de la asignación de entidades JPA
Pregunta
Estoy buscando una manera fácil de extender el mapeo JPA existente. La idea es la siguiente:
Tengo un proyecto EAR con el módulo EJB3 + JPA que tiene clase A anotada y asignada a la tabla class_a. Pero quiero que algún otro módulo (otro módulo EJB) tenga ClassB que agregue más propiedades a ClassA (¿extender?).
Una forma en la que pensé es simplemente agregar esos campos adicionales a la tabla class_a y ejecutar consultas que no sean HQL para recuperar esos datos. No es bueno ya que tengo que hacer muchas cosas a mano: mapeo de tipos, mapeo de columnas, etc.
He hecho una comprobación simple, pero parece que no puedo extender ClassA en el segundo módulo (por ClassB) porque usan EntityManagerFactories diferentes y algunas clases del primer módulo no se ven en el segundo y viceversa.
Ya he visto < jar-file > etiqueta dentro de persistence.xml. Necesito algo así, pero su uso requiere que el archivo aparezca en el primer módulo y debe existir (no se saltará si no se encuentra). ¿Hay algo así que se pueda poner en el módulo de extensión (segundo) y no en el extensible (el primero)?
Si hay una manera de extender el mapeo JPA en tiempo de ejecución, sería genial. ¿Hay tal manera? ¿Hay otra solución a mi problema?
Solución
La solución implementada es la siguiente. Tengo un jar y dos módulos EJB:
-
La jarra es la base. Contiene las entidades base y la interfaz local para la extensión:
@Entity public class BaseEntity { public long id; @Id @GeneratedValue public long getId() {... ... other variables, getters, setters ... } @Local public interface EntitiyManagerWithExtendedEntitiesInterface { public EntityManager getEntityManager; }
-
El primer módulo EJB es el que extenderá las entidades base y agregará EJB para obtener su administrador de entidades. Este módulo también incluye
persistence.xml
con<jar-file>../path_to_first_jar_file.jar</jar-file>
línea.@Entity ... discriminator annotations public class ExtEntity extends BaseEntity { ... additional fields here } @Stateless public class EntitiyManagerWithExtendedEntitiesBean implements EntitiyManagerWithExtendedEntitiesInterface { @PersitenceContext EntityManager em; public EntityManager getEntityManager() { return em; } }
-
El segundo módulo EJB tendrá EJB que solo necesitan el jar para compilar pero requieren el primer EJB para ejecutarse (requiere un EJB que implementará la interfaz
EntitiyManagerWithExtendedEntitiesInterface
).@Stateless public class getSomeEntity { @EJB EntitiyManagerWithExtendedEntitiesInterface ext; EntityManager em; @PostConstruct public void injectEntityManager() { em = ext.getEntityManager(); } public void ejbInterfaceMethod() { ... method that uses em variable (EntityManager) } }
De esta forma, el servidor de aplicaciones tendrá que gestionar las dependencias entre módulos y puedo intercambiar fácilmente el primer módulo EJB para incluir otro conjunto de entidades de extensión.