You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomee.apache.org by Alexander Saint Croix <sa...@gmail.com> on 2007/12/13 04:29:43 UTC

Alternatives to specifying persistence provider in component jars?

Hello,

I'm working on an application that at the moment includes a single
(proof-of-concept) entity bean in my main web application WAR, and also
large number of entity beans which are JAR'd in the WEB-INF/lib.

Knowing that the persistence management is all outboard and not contained
inside of OpenEJB, perhaps you guys could help me with a matter of
configuration anyway.

I wonder whether there is any way for me to NOT include the <provider> and
<properties> elements defining the persistence provider implementation,
connection URL, connection driver name, username and password in the
persistence.xml file for my entity/POJO jar (the one inside of WEB-INF/lib),
but rather configure that specific portion of the persistence.xml file
inside of the context of the application that is using these beans?  It
doesn't seem to be any of the POJO JAR's business what type of persistence
provider is being used to persist its contents.

I've attached an example of the <provider> and <properties> elements I wish
to exclude below.  I want to define classes but not persistence provider
information in the entity JARs, and define the persistence provider for
these persistence-units once at the container level.  Is this possible, and
if so, how might I accomplish that separation with OpenEJB?

Regards,
--
Alexander R. Saint Croix



<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
    <persistence-unit name="example" transaction-type="RESOURCE_LOCAL">
        <provider>
            org.apache.openjpa.persistence.PersistenceProviderImpl
        </provider>

        <class>org.eremite.SomeBeanInThisJar</class>

        <properties>
            <property name="openjpa.jdbc.SynchronizeMappings"
                      value="buildSchema"/>

            <property name="openjpa.ConnectionURL"
                      value="jdbc:mysql://localhost/corm"/>

            <property name="openjpa.ConnectionDriverName"
                      value="com.mysql.jdbc.Driver"/>

            <property name="openjpa.ConnectionUserName"
                      value="username"/>

            <property name="openjpa.ConnectionPassword"
                      value="password"/>
        </properties>
    </persistence-unit>
</persistence>

Re: Alternatives to specifying persistence provider in component jars?

Posted by David Blevins <da...@visi.com>.
On Dec 12, 2007, at 9:16 PM, Alexander Saint Croix wrote:

> Thanks for the fast response, David.
>
> The ability to remove the following four properties is very helpful  
> and a
> great start:
>
> Namely the following:
>>  javax.persistence.provider
>>  javax.persistence.transactionType
>>  javax.persistence.jtaDataSource
>>  javax.persistence.nonJtaDataSource
>>
>
> While packaging up my component beans, I'd rather not specify the
> persistence provider from inside the component JAR.  If someone  
> wanted to
> use my beans with a different persistence provider they should be able
> to--that's what these component JARs are designed for.  So, the plan  
> at the
> moment is to write OpenJPA-tailored persistence.xml files, and in  
> the future
> if someone wants to use another PP, I'll have to ship JARs with that  
> one
> line of code different in the XML file.
>
> Just seems off.  There should be some way to override that at  
> least.  That
> would make packaging these component JARs much more straight-forward  
> for me.

Maybe I wasn't clear enough.  The above properties are specified on a  
server level and supply the defaults for all apps when the leave out  
any of the following elements from their xml (use of ${} show for  
illustrative purposes):

     <persistence-unit name="my-unit" transaction-type="$ 
{javax.persistence.transactionType}">
         <provider>${javax.persistence.provider}</provider>
         <jta-data-source>${javax.persistence.jtaDataSource}</jta-data- 
source>
         <non-jta-data-source>${javax.persistence.nonJtaDataSource}</ 
non-jta-data-source>
     </persistence>

Strictly speaking this all you *must* supply in your persistence.xml:

   <persistence xmlns="http://java.sun.com/xml/ns/persistence"  
version="1.0">
      <persistence-unit name="my-unit"/>
   </persistence>

... along with the following two properties at the server level:

   javax.persistence.jtaDataSource
   javax.persistence.nonJtaDataSource

We have a file called conf/system.properties you can use to make  
declaring system properties easier in a standalone server.  For  
embedded environments you're welcome to just add them via  
System.setProperty() or even pass them in as parameters to "new  
InitialContext(props)".

> While fully defining persistence units at the OpenEJB level would be  
> great,
> some sort of override function might be better.  "Configuration  
> shadowing",
> or some such.

You don't have to fully define anything in OpenEJB, ever. :)

All of our configuration works on an override basis so you only have  
to specify what you want to be different.  For example if you took  
your openejb.xml file and deleted all the properties from every  
Container, Resource, etc., it would still work.

The default values for absolutely everything configurable via an  
openejb.xml are declared in xml files that we pack in our jars. When  
you declare something via an openejb.xml file, we go find the  
"template" that will provide the defaults, we then override them with  
the values you supplied via your openejb.xml, then we override again  
with any values you supplied via system properies (the format of that  
is <component-id>.<property-name>=<property-value>).  The result is  
then "instantiated" and becomes a real running component (e.g.  
Container, Resource, etc.).

Strictly speaking you really don't need to declare anything via your  
openejb.xml, namely containers, as we will create them for you as  
needed.  You really only need to declare what you intend to override.   
This is one of the ways we achieve embedded testing so flawlessly.

We also have tool you can use that will print out a fully canonical  
version of your running configuration so you can see one big flat list  
of everything that exists and what its properties are.  See http://openejb.apache.org/3.0/configuration-properties.html

-David



Re: Alternatives to specifying persistence provider in component jars?

Posted by Alexander Saint Croix <sa...@gmail.com>.
Thanks for the fast response, David.

The ability to remove the following four properties is very helpful and a
great start:

Namely the following:
>   javax.persistence.provider
>   javax.persistence.transactionType
>   javax.persistence.jtaDataSource
>   javax.persistence.nonJtaDataSource
>

While packaging up my component beans, I'd rather not specify the
persistence provider from inside the component JAR.  If someone wanted to
use my beans with a different persistence provider they should be able
to--that's what these component JARs are designed for.  So, the plan at the
moment is to write OpenJPA-tailored persistence.xml files, and in the future
if someone wants to use another PP, I'll have to ship JARs with that one
line of code different in the XML file.

Just seems off.  There should be some way to override that at least.  That
would make packaging these component JARs much more straight-forward for me.



> Note that the javax.persistence.provider will default to OpenJPA (i.e.
> org.apache.openjpa.persistence.PersistenceProviderImpl).  While that's
> nice, it doesn't allow you to pass the vendor specific properties,
> namely the truly amazing "openjpa.jdbc.SynchronizeMappings" that will
> basically allow you to squeak by not having to create or drop tables.


Got it.  I'll just keep the <provider> reference in my component JARs for
now.

While fully defining persistence units at the OpenEJB level would be great,
some sort of override function might be better.  "Configuration shadowing",
or some such.

The validation features should come in quite handy soon.  For now, back to
defining entity relations.

Cheers!
--
Alexander R. Saint Croix

Re: Alternatives to specifying persistence provider in component jars?

Posted by David Blevins <da...@visi.com>.
Hi Alex,

We actually do have to do quite a bit of linking and other work to  
support JPA, so you definitely came to the right list.  I'm ripping  
that code up right now in fact.

While you do have to have a persistence.xml file for your application,  
*some* of the values in a persistence.xml can be supplied via system  
properties and left out of your persistence.xml.

Namely the following:
   javax.persistence.provider
   javax.persistence.transactionType
   javax.persistence.jtaDataSource
   javax.persistence.nonJtaDataSource

Note that the javax.persistence.provider will default to OpenJPA (i.e.  
org.apache.openjpa.persistence.PersistenceProviderImpl).  While that's  
nice, it doesn't allow you to pass the vendor specific properties,  
namely the truly amazing "openjpa.jdbc.SynchronizeMappings" that will  
basically allow you to squeak by not having to create or drop tables.

We don't yet have the ability to fully define persistence units at the  
openejb.xml level, but that definitely is a feature I've thought of  
adding.

Along the lines of hooking your application up to persistence units  
defined in a persistence.xml, I added some great code for the upcoming  
beta 2 that performs some pretty bullet proof validation of your app.   
Some sample validation messages you might see in beta 2 are:


Mistaken use of @PersistenceUnit on an EntityManager reference.  Use  
@PersistenceContext for ref "org.superbiz.injection.jpa.MoviesImpl/ 
entityManager"

Mistaken use of @Resource on an EntityManager reference.  Use  
@PersistenceContext for ref "org.superbiz.injection.jpa.MoviesImpl/ 
entityManager"

Persistence unit not found for  
@PersistenceContext(name="entityManager", unitName="movie-unnit").   
Available units [movie-unit]


We also have a new example for showing dependency injection of JPA  
EntityManagers.  It's fun to run it and attempt to break the app by  
adding, changing, or removing persistence units or references to them.  
If you find a way that we don't check for, I'll by you a book on  
amazon.  And as usual, all validation come in all-at-once "compiler"  
format, so it should be possible to spot all your mistakes in one go  
avoiding countless "small fix, compile, redeploy, fail, repeat" cycles.

The new example:
http://svn.apache.org/repos/asf/openejb/trunk/openejb3/examples/injection-of-entitymanager/

-David

On Dec 12, 2007, at 7:29 PM, Alexander Saint Croix wrote:

> Hello,
>
> I'm working on an application that at the moment includes a single
> (proof-of-concept) entity bean in my main web application WAR, and  
> also
> large number of entity beans which are JAR'd in the WEB-INF/lib.
>
> Knowing that the persistence management is all outboard and not  
> contained
> inside of OpenEJB, perhaps you guys could help me with a matter of
> configuration anyway.
>
> I wonder whether there is any way for me to NOT include the  
> <provider> and
> <properties> elements defining the persistence provider  
> implementation,
> connection URL, connection driver name, username and password in the
> persistence.xml file for my entity/POJO jar (the one inside of WEB- 
> INF/lib),
> but rather configure that specific portion of the persistence.xml file
> inside of the context of the application that is using these beans?   
> It
> doesn't seem to be any of the POJO JAR's business what type of  
> persistence
> provider is being used to persist its contents.
>
> I've attached an example of the <provider> and <properties> elements  
> I wish
> to exclude below.  I want to define classes but not persistence  
> provider
> information in the entity JARs, and define the persistence provider  
> for
> these persistence-units once at the container level.  Is this  
> possible, and
> if so, how might I accomplish that separation with OpenEJB?
>
> Regards,
> --
> Alexander R. Saint Croix
>
>
>
> <persistence xmlns="http://java.sun.com/xml/ns/persistence"  
> version="1.0">
>    <persistence-unit name="example" transaction-type="RESOURCE_LOCAL">
>        <provider>
>            org.apache.openjpa.persistence.PersistenceProviderImpl
>        </provider>
>
>        <class>org.eremite.SomeBeanInThisJar</class>
>
>        <properties>
>            <property name="openjpa.jdbc.SynchronizeMappings"
>                      value="buildSchema"/>
>
>            <property name="openjpa.ConnectionURL"
>                      value="jdbc:mysql://localhost/corm"/>
>
>            <property name="openjpa.ConnectionDriverName"
>                      value="com.mysql.jdbc.Driver"/>
>
>            <property name="openjpa.ConnectionUserName"
>                      value="username"/>
>
>            <property name="openjpa.ConnectionPassword"
>                      value="password"/>
>        </properties>
>    </persistence-unit>
> </persistence>