Estendendo mapeamento entidade JPA
Pergunta
Eu estou procurando uma maneira fácil para estender o mapeamento de JPA existente. A idéia é a seguinte:
Eu tenho um projeto EAR com módulo de EJB3 + JPA que tem ClassA anotados e mapeado para class_A mesa. Mas eu quero que algum outro módulo (outro módulo EJB) para ter ClassB que adiciona mais propriedades para ClassA (estender?).
Uma maneira que eu pensava sobre, é apenas para adicionar esses campos adicionais para a mesa de class_A e executar não HQL consultas para recuperar esses dados. Não é bom como eu tenho que fazer muitas coisas à mão:. Mapeamento de tipo, mapeamento de coluna, etc
Eu fiz verificação simples, mas parece que eu não posso estender ClassA no segundo módulo (por ClassB) porque eles usam diferentes EntityManagerFactories e algumas aulas do primeiro módulo não são vistos pelo segundo e vice-versa.
Eu já vi a tag <-arquivo jar> dentro persistence.xml. Eu preciso de algo assim, mas o uso de que ele necessita para ter esse arquivo listado no primeiro módulo e deve existir (Não vai pular se não for encontrado). Existe algo parecido, que pode ser colocado no módulo de extensão (segunda) e não o extensível (o primeiro)?
Se há uma maneira de estender o mapeamento de JPA em tempo de execução seria ótimo. Existe tal maneira? Existe uma outra solução para o meu problema?
Solução
A solução implementada é a seguinte. Eu tenho uma jarra e dois módulos EJB:
-
O frasco é a base um. Ele mantém as entidades de base e interface local para a extensão:
@Entity public class BaseEntity { public long id; @Id @GeneratedValue public long getId() {... ... other variables, getters, setters ... } @Local public interface EntitiyManagerWithExtendedEntitiesInterface { public EntityManager getEntityManager; }
-
O primeiro módulo EJB é o que irá estender as entidades de base e adicionar EJB para obtê-lo do gerenciador de entidade. Este módulo também inclui
persistence.xml
com linha<jar-file>../path_to_first_jar_file.jar</jar-file>
.@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; } }
-
O segundo módulo EJB terá EJBs que precisam apenas o frasco para compilar mas requerem o primeiro EJB para executar (requerem um EJB que irá implementar a interface
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) } }
Desta forma, o servidor de aplicação terá de gerir as dependências entre os módulos e posso facilmente trocar o 1º módulo EJB para incluir um outro conjunto de entidades de extensão.