In standard EJB 3, when injecting entity manager, persistence unit (which refers to datasource) is hardcoded into annotation: (or alternatively xml file)
@PersistenceContext(unitName = "myunit")
private EntityManager entityManager;
Is there a way to use an entity manager but to select data source by name at runtime?
Now at runtime you can build entity-manager for the required persistence-unit. Create separate persistence-units for each data-source.
This will create and return an EntityManagerFactory for the named persistence unit using the given properties. Therefore you can change the properties at runtime accordingly.
Using EclipseLink, You can set a DataSource configured in your app server.
PU_NAME
refers to the name used in the file persistence.xmldataSource refers name used in the app server for the jdbc Resource as "jdbc/sample"
It is possible! I've done it and it works under JBoss AS and WebSphere.
I use a custom persistence provider which extends
org.hibernate.ejb.HibernatePersistence
(you need to modify aprivate static final
field to set your persistence provider name intoorg.hibernate.ejb3.Ejb3Configuration.IMPLEMENTATION_NAME
: this is a kind of black magic but it works). Make sure yourpersistence.xml
's persistence units have the custom provider set in the<provider>
tag and your custom provider is registered inMETA-INF/services/javax.persistence.spi.PersistenceProvider
.My provider overrides the
createContainerEntityManagerFactory(PersistenceUnitInfo,Map)
method called the Java EE container as such (for JTA datasource but it would be easy to do it also for non JTA datasource):The
createEntityManagerFactory(String,Map)
also overriden but is much simpler:Note that I only wrote here the core code. In fact, my persistence provider has a lot of other functionalities:
I want to indicate that the usage of
recommended in the answer of Nayan is classified by the JPA Specification (JSR 317) as follows (footnote in "9.2 Bootstrapping in Java SE Environments"):
So this isn't a standard solution for EJB. Anyway, I can confirm that this is working in EclipseLink.
Note: I'm not yet allowed to post this as a comment.