I'd start by putting every thing in a single jar with a persistence.xml. Once you get that working, then you can attempt to split it up.

As for actually splitting it up, I think there are two ways to go about it, although I've never tried either.

1) One persistence-unit with code spread amongst several dependent jars. I'm not sure if OpenJPA will scan the whole class path or just the one jar containing the persistence.xml file, so you may have to explicitly list your persistent classes in the persistence.xml file.

2) Multiple persistence-units. This will only work if the multiple units are island meaning they don't have relationships between entities in separate units.

I think the one persistence-unit option will be the best, as keeping to one persistence-unit means you have one JPA instance managing everything. This way guarantees you only get one cache and one database connection used. In OpenEJB we have code to detect multiple connections to the same database in one transaction and coalesce them into a single connection, but not all JEE servers do this. If you do end up with multiple database connections, you will need a database that supports XA transactions (last time I checked mySQL didn't). It is possible that a smart JPA implementation will recognize that is has two persistence-units to the same database and automagically configures itself to use a single DB connection, but I wouldn't count on it from any implementation except OpenJPA.

Anyway, I'd sick everything in one unit and optimize the packaging at the end of development.

-dain

On Dec 17, 2007, at 7:19 AM, Alexander Saint Croix wrote:

Thanks for the help, David.

I broke up the component library to make it modular, as there are presently
between 70-100 entities total.  I'm really REALLY not interested in
combining those JARs, and have been operating on a couple of assumptions
about persistence units and how they must be packaged.

I thought that each component JAR needed to include its own persistence.xmlfile.

The spec says:

A persistence unit may be packaged within one or more jar files contained
within a WAR


But also:

Only one persistence unit of any given name may be defined
within a single EJB-JAR file, within a single WAR file, within a single
application client jar, or within
an EAR (in the EAR root or lib directory).


Do my component JARs need to have persistence.xml files at all? None of
them are the root of the persistence unit--that seems to be the WAR.
Shouldn't I define the persistence.xml file in the web app and reference the
JARs from there?  It would certainly simplify matters.

Also, in which file do I configure my DataSource in embedded OpenEJB?

Regards,
--
Alex





On Dec 17, 2007 2:13 AM, David Blevins <[EMAIL PROTECTED]> wrote:

On Dec 16, 2007, at 10:32 PM, Alexander Saint Croix wrote:

I am deploying in an embedded OpenEJB environment in Tomcat.


   ...
       // inside of the doGet(...) method:

       FirstEntity ent1 = new FirstEntity();
       ent1.setName("Entity name");
       ent1.setDescription("Entity description");
       ent1.setType("Entity type");

       mgr.persist(ent1);

       SecondEntity ent2 = new SecondEntity();
       ent2.setName("Entity name 2");
       ent2.setDescription("Entity description 2");
       ent2.setSecondType("Entity type 2");

       mgr.persist(ent2);


@Stateless
public class DefaultBeanManager implements BeanManager {

   @PersistenceUnit(unitName="corm-base")
   EntityManagerFactory emf;

   @PersistenceUnit(unitName="corm-party")
   EntityManagerFactory emf2;

   public void persist(FirstEntity a) {

       System.setProperty("openjpa.ConnectionDriverName", "
com.mysql.jdbc.Driver");
       System.setProperty("openjpa.ConnectionURL",
"jdbc:mysql://localhost/corm");
       System.setProperty("openjpa.jdbc.SynchronizeMappings",
"buildSchema");
       System.setProperty("openjpa.ConnectionUserName", "root");
       System.setProperty("openjpa.ConnectionPassword",
"n00p455wyrd");

       EntityManager em = emf.createEntityManager();
       em.getTransaction().begin();
       em.persist(a);
       em.getTransaction().commit();
       em.close();

   }

   public void persist(SecondEntity a) {

       System.setProperty("openjpa.ConnectionDriverName", "
com.mysql.jdbc.Driver");
       System.setProperty("openjpa.ConnectionURL",
"jdbc:mysql://localhost/corm");
       System.setProperty("openjpa.jdbc.SynchronizeMappings",
"buildSchema");
       System.setProperty("openjpa.ConnectionUserName", "root");
       System.setProperty("openjpa.ConnectionPassword",
"n00p455wyrd");

       EntityManager em = emf2.createEntityManager();
       em.getTransaction().begin();
       em.persist(a);
       em.getTransaction().commit();
       em.close();
   }
}


<persistence xmlns="http://java.sun.com/xml/ns/persistence";
version="1.0">
   <persistence-unit name="corm-party" transaction-
type="RESOURCE_LOCAL">
   </persistence-unit>
</persistence>

How should I correctly configure the ConnectionDriverName property for multiple persistence units so that these component jars can cooperate?

Definitely do not set ConnectionDriverName at all, likewise for any of
the OpenJPA properties that smell of "let us make the datasource for
you".  You need to configure your datasource in Tomcat or OpenEJB
(either is fine as we sync the environments together), then you *must*
either a) set these two system properties:

 javax.persistence.jtaDataSource=java:openejb/Resource/myDataSource
 javax.persistence.nonJtaDataSource=java:openejb/Resource/
myNonJtaDataSource

or b) set them in each persistence.xml via:
   <persistence-unit name="corm-party">
     <jta-data-source>java:openejb/Resource/myDataSource</jta-data-
source>
     <non-jta-data-source>=java:openejb/Resource/myNonJtaDataSource</
non-jta-data-source>
   </persistence-unit>

The second and more important.  Why do you want to split these Entity
beans up into so many persitence-units.  Is this a packaging concern
or is it really your intent to have several completely separate
caches, each with it's own connection to the database, and each
managing it's own transaction with no cooperation and visibility to
the other?  I suspect the answer is no as you have attempted to point
them all at the same database. If you start sharing data between them
you could wind up with some serious data integrity issues.

I can recommend a better approach once I better understand your
motivation.

-David



Reply via email to