Estensione del mapping delle entità JPA
Domanda
Sto cercando un modo semplice per estendere la mappatura JPA esistente. L'idea è la seguente:
Ho un progetto EAR con modulo EJB3 + JPA che ha ClassA annotato e mappato alla tabella class_a. Ma voglio che un altro modulo (un altro modulo EJB) abbia ClassB che aggiunge più proprietà a ClassA (estensione?).
Un modo in cui ho pensato, è solo quello di aggiungere quei campi aggiuntivi alla tabella class_a ed eseguire query non HQL per recuperare quei dati. Non va bene perché devo fare molte cose a mano: mappatura dei tipi, mappatura delle colonne, ecc.
Ho fatto un semplice controllo ma sembra che non riesca a estendere ClassA nel secondo modulo (da ClassB) perché usano diverse EntityManagerFactories e alcune classi dal primo modulo non sono viste dal secondo e viceversa.
Ho già visto < jar-file > tag all'interno di persistence.xml. Ho bisogno di qualcosa del genere, ma il suo utilizzo richiede che il file sia elencato nel primo modulo e deve esistere (non salterà se non trovato). C'è qualcosa del genere, che può essere inserito nel modulo di estensione (il secondo) e non in quello estensibile (il primo)?
Se c'è un modo per estendere la mappatura JPA in fase di esecuzione, sarebbe fantastico. C'è un modo simile? C'è un'altra soluzione al mio problema?
Soluzione
La soluzione implementata è la seguente. Ho un vaso e due moduli EJB:
-
Il barattolo è quello di base. Contiene le entità di base e l'interfaccia locale per l'estensione:
@Entity public class BaseEntity { public long id; @Id @GeneratedValue public long getId() {... ... other variables, getters, setters ... } @Local public interface EntitiyManagerWithExtendedEntitiesInterface { public EntityManager getEntityManager; }
-
Il primo modulo EJB è quello che estenderà le entità di base e aggiungerà EJB per ottenere il gestore delle entità. Questo modulo include anche
persistence.xml
con<jar-file>../path_to_first_jar_file.jar</jar-file>
riga.@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; } }
-
Il secondo modulo EJB avrà EJB che richiedono solo il jar per la compilazione ma richiedono l'esecuzione del primo EJB (richiede un EJB che implementerà
EntitiyManagerWithExtendedEntitiesInterface
interfaccia).@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) } }
In questo modo il server delle applicazioni dovrà gestire le dipendenze tra i moduli e posso facilmente scambiare il primo modulo EJB per includere un altro set di entità di estensione.