views:

777

answers:

1

I'm looking for an easy way to extend existing JPA mapping. The idea is as follows:

I have an EAR project with EJB3+JPA module which has ClassA annotated and mapped to table class_a. But I want some other module (another EJB module) to have ClassB which adds more properties to ClassA (extend?).

One way that I though about, is just to add those additional fields to the class_a table and run non-HQL queries to retrieve that data. It's not good as I have to do many things by hand: type mapping, column mapping, etc.

I've done simple check but it seems that I can't extend ClassA in the second module (by ClassB) because they use different EntityManagerFactories and some classes from the first module are not seen by the second and vice versa.

I've already seen the <jar-file> tag inside persistence.xml. I need something like that, but the use of it requires to have that file listed in the first module and it must exist (It won't skip if not found). Is there something like that, that can be put on the extending module (second one) and not the extendable one (the first)?

If there's a way to extend the JPA mapping in run-time it would be great. Is there such a way ? Is there another solution to my problem ?

A: 

The implemented solution is as follows. I have one jar and two EJB modules:

  1. The jar is the base one. It holds the base entities and local interface for the extension:

    @Entity
    public class BaseEntity {
        public long id;
        @Id @GeneratedValue
        public long getId() {...
        ... other variables, getters, setters ...
    }
    
    
    @Local
    public interface EntitiyManagerWithExtendedEntitiesInterface {
        public EntityManager getEntityManager;
    }
    
  2. The first EJB module is the one that will extend the base entities and add EJB to get it's entity manager. This module also includes persistence.xml with <jar-file>../path_to_first_jar_file.jar</jar-file> line.

    @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;
        }
    }
    
  3. The second EJB module will have EJBs that need only the jar to compile but require the first EJB to run (require an EJB that will implement EntitiyManagerWithExtendedEntitiesInterface interface).

    @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)
        }
    }
    

This way the application server will have to manage the dependencies between modules and I can easily swap the 1st EJB module to include another set of extension entities.

Vitaly Polonetsky