10
votes

basically, what i wanna do is assigning 'unitName' attribute of @PersistenceContext with a value that i will get from the Session at runtime.

in details;

my application will be a SaaS application and i will have separate DBs for every different tenants. i am using Glassfishv3 and managing the entities container-based so i dont get any instance from EntityManagerFactory explicitly. All i am doing for creating an entity manager is ;

@PersistenceContext(unitName = "DBNAME")
private EntityManager entityManager;

i need to pass unitName attribute according to the current user. it shouldn't be hard-coded.

I have updated Eclipselink 2.3 but all examples are creating an instance from EMF which you can pass property Map like

Map memberProps = new HashMap();
memberProps.put("memberPu1", props1);
memberProps.put("memberPu2", props2);

Map props = new HashMap();
props.put("eclipselink.jdbc.exclusive-connection.mode", "Always");
props.put("eclipselink.composite-unit.properties", memberProps);

EntityManager em = emf.createEntityManager(props);

unlikely in my app, container does that job so i am not being able to do this

EntityManager em = emf.createEntityManager(props);

Even though i have all the persistence units and classes in my persistence.xml by using JNDI definitions, i am not being able to tell app server which DB(persistence unit) it should use at the time

any help would be appreciated

2
This question help me to find a solution for a similar case. I thik can be util: stackoverflow.com/questions/5104185/…Monnie

2 Answers

9
votes

Values in annotations cannot be assigned at runtime, and therefore you will need to find a strategy where you can create multiple PersistenceContexts. If you can use CDI, it will probably make your life easier.

With CDI you might be able to create a producer as follows:

public class EntityManagerProducer {

  @PersistenceContext(unitName="firstUnit") private EntityManager firstEntityManager;
  @PersistenceContext(unitName="secondUnit") private EntityManager secondEntityManager;

  @Produces
  public EntityManager getEntityManager(InjectionPoint injectionPoint) {
     if(<your_first_criteria>) {
       return firstEntityManager;
     } else if (<your_second_criteria>) {
       return secondEntityManager;
     }
  }

Then you can use your producer method in e.g. your DAO:

@Inject private EntityManager entityManager;

EDIT: I would probably recommend to use a @Qualifier annotation as it makes it clear where are you getting the EntityManager from.

1
votes

You need to use an application managed persistence unit, not container.

i.e. Persistence.createEntityManagerFactory()

You can still use JTA, just not injection.