persistence@glassfish.java.net

Re: can you set the persistence-unit data-source at runtime?

From: Sanjeeb Kumar Sahoo <Sanjeeb.Sahoo_at_Sun.COM>
Date: Sat, 21 Oct 2006 09:59:41 +0530

data-source name is not needed at compile time. You can edit it just
before deployment step. If you don't know the data-source name until run
time, then too late. It's a different matter that some appserver may not
have a deployment tool to edit the persistence.xml.

By the way, even if there were an API to set DataSource in
EntityManagerFactory, how would you have called that API with a
data-source? To call that API, you need a data-source which you can
obtain only by looking up JNDI tree. Are you saying that your
application gets the JNDI name from user at runtime. Why can't you know
the JDNI name at deployment time?

Now coming to the rational behind why data-source is used in
persistence.xml:
Unlike web app or EJB, a persistence unit is not a component by itself
and hence it does not have a naming environment of its own. More over,
since some persistence units can be shared by multiple components, they
can't assume that they have a unique naming environment. So, you have to
use the actual JNDI name of the datasource in persistence.xml. But,
actually, that is not that bad. Even if you were allowed to specify a
resource-ref-name as opposed to specifying the actual resource-name, you
any way had to bind the resource-ref to an actual resource at deployment
time, right? So, I don't understand how any dependency injection would
have helped because injected resource is resolved at application
deployment/load time.

An emf is bound to one data-source because an emf produces homogeneous
entity managers. When the factory is created, it is already configured
with a data-source. After that each em produced by the emf will connect
to the same data-source. Hence, user is not be allowed to call
emf.setDataSource() or emf.createEntityManager(DataSource ds).

I don't understand why you can't know the data source name at deployment
time. If you really want to decide which database to connect at runtime,
then explore the option of creating EMF using
Persistence.createEntityManagerfactory(emfName, properties). You can
specify the JDBC connection URL in the properties, but your app will
have to rely on vendor specific property.

Thanks,
Sahoo

Nitin Nahata wrote:
> I have a web application that needs to talk to a particular JDBC
> data-source registered in the appserver JNDI tree. But my application
> does not know the JNDI-name of this data-source until after the app
> has been deployed and started.
>
> So I cannot set the correct value for the <jta-data-source> element in
> persistence.xml while building the application. I would like to be
> able to "inject" it at runtime.
>
> I am not aware of the implementation details but I guess one way to do
> this could have been to have below methods in
> javax.persistence.EntityManagerFactory:
>
> 1. setDataSource( javax.sql.DataSource ds ) or
> 2. createEntityManager( javax.sql.DataSource ds )
> 3. or both 1 and 2
>
> Which would let you have code like below:
>
> public class AController {
>
> @PersistenceUnit(unitName = "myPU")
> private EntityManagerFactory emf;
>
> //constructor
> AController( javax.sql.DataSource ds ) {
> emf.setDataSource( javax.sql.DataSource ds );
> }
>
> private EntityManager getEntityManager( ) {
> return emf.createEntityManager();
> }
>
> public List<A> getAll() {
> EntityManager em = getEntityManager();
> ....
> ....
> }
>
> }
>
> But since I dont see the above methods in the api, I was wondering if
> there is some other way to achieve this?
>
> Thanks
> Nitin
>
>
>
>
> On 10/20/06, Marina Vatkina <Marina.Vatkina_at_sun.com> wrote:
>> Hi Nitin,
>>
>> Can you be a bit more specific at what are you trying to accomplish?
>>
>> thanks,
>> -marina
>>
>> Nitin Nahata wrote:
>> > data-source for a persistence-unit is set in the persistence.xml file.
>> > Which means that it should be known at compile time.
>> >
>> > Is there a way to set the data-source at runtime instead?
>> >
>> > Thanks
>> > Nitin
>>
>>