On Feb 17, 2009, at 7:44 AM, <thomas.th.hamac...@partner.bmw.ch> <thomas.th.hamac...@partner.bmw.ch > wrote:

Do I have any chance to get the hashcode as well?

I could do the workaround to ignore the id and imply that the persistence-unit is unique, but it would even be cleaner, if I would look for the exact jndi-name.

But as I do this programatically I currently never know the id exactly.

There's no convenient way to get the hashcode.

Just another question how to proceed further: I know I can create a new EntityManager from the EntityManagerFactory, but is this the way I should go here?

Will this be the entityManager which is also injected into the other SessionBeans by openEJB or will it be another one?

The reason I am asking is, that I also use an EntityManager in my Services, which I call within my tests. So wouldn´t it cause some troubles if I work with different EntityManagers?

That's really the big question. I'm not exactly sure how your tests are written, but it would be fine to use them both as long as it was understood they are two completely different Persistence Contexts (i.e. caches). This is pretty much how things will look at runtime anyway -- i.e. multiple threads and transactions each with it's own persistence context. If you don't attempt to use them together in the same transaction and you don't attempt to create two transactions in the same thread simultaneously, it should be fine.

The bigger thing will be to respect the mode in which the persistence unit in question is meant to work. If it is a RESOURCE_LOCAL unit, you'll want to use the EntityTransaction API to transactionally demark you work with the created EntityManager. If it is a JTA (the default) persistence unit, you'll want begin/commit transactions via either a UserTransaction or the TransactionManager directly when you work with the EntityManager.


-David







Thanks a lot



Thomas











Hi Thomas,



We actually do have something similar internally, but the trick is that persistence unit names are not required to be unique outside the persistence.xml file (i.e. it's legal to have multiple persistence.xml files in various modules in your app all with the same name despite that they are different persistence units). So currently we generate an id for the persistence.xml file itself and tack that on to the end of the persistence unit name before registering it in JNDI. The format is:

"java:openejb/PersistenceUnit/" + unitName + " " + id



The id is a hashCode we generate to identify the exact persistence.xml file.

This is more for our purposes internally, but it is possible to get a list of them outside an EJB or Servlet. Inside a Servlet or EJB you don't currently have access to java:openejb though we plan to add that.

Here's a small example:

The persistence.xml file



<persistence xmlns="http://java.sun.com/xml/ns/persistence";<http://java.sun.com/xml/ns/persistence%22 >; version="1.0">

   <persistence-unit name="orange-unit">
     <jta-data-source>Orange</jta-data-source>
     <non-jta-data-source>OrangeUnmanagedamanged</non-jta-data-source>
   </persistence-unit>
   <persistence-unit name="lime-unit">
     <jta-data-source>Lime</jta-data-source>
     <non-jta-data-source>LimeUnmanagedamanged</non-jta-data-source>
   </persistence-unit>
 </persistence>

If you executed code like this in your test case:

   // Do not pass in LocalInitialContextFactory
   Context context = new InitialContext();

   context = (Context) context.lookup("java:openejb/PersistenceUnit");

   Map<String,Object> map = Debug.contextToMap(context);
   for (String key : map.keySet()) {
       System.out.println(key);
   }

You see this in the output:

  "lime-unit 3506402"
  "orange-unit 3506402"



Looking up these will give you the internal EntityManagerFactory we use to create the various EntityManager instances at runtime (i.e. transaction start for TRANSACTION scope or stateful session bean creation for EXTENDED scope).

Note the "Debug.contextToMap" call is just you standard iterate over JNDI code. Here it is if you want it:

public static Map<String,Object> contextToMap(Context context) throws NamingException { Map<String, Object> map = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);

       contextToMap(context, "", map);
       return map;
   }



public static void contextToMap(Context context, String baseName, Map<String,Object> results) throws NamingException { NamingEnumeration<Binding> namingEnumeration = context.listBindings("");

       while (namingEnumeration.hasMoreElements()) {
           Binding binding = namingEnumeration.nextElement();
           String name = binding.getName();
           String fullName = baseName + name;
           Object object = binding.getObject();
           results.put(fullName, object);
           if (object instanceof Context) {


contextToMap((Context) object, fullName + "/", results);

           }
       }
   }



Further note to future readers who might want to iterate over the entire java:openejb tree. Caution should be used with the java:openejb/ejb/, java:openejb/Deployment/, and java:openejb/ client/ sections of the tree as they will contain any Stateful session bean's you have in your platform and calling "binding.getObject()" on those will cause stateful session bean instances to be created.

In terms of future functionality, we would like to provide an alternate JNDI view of the persistence units that doesn't involve the unique ID and simply is "unit name".

-David





Reply via email to