Using persistence.xml and ejb3unit

Lately the “Don’t Repeat Yourself”, or DRY, principle is quite popular. I like it quite a bit myself. However, when using ejb3unit, I found that I had to maintain two lists of persistence classes – one for ejb3unit, and one for the java persistence system. Today I finally decided to address this problem, and I haven’t regretted it!

I wrote a method which finds and parses my META-INF/persistence.xml and returns an array of classes from it. I can pass this to the constructor of the BaseSessionBeanFixture when I create the test case object.

Here it is:



 public static Class[] getDbClasses() {

        URL[] persistenceUnits;

 	try {

 		persistenceUnits = Classpath.search("META-INF/", "persistence.xml");

 	} catch (IOException e) {

 		throw new Error(e);

 	}

        Set> classes = new HashSet>();

        for (int i = 0; i < persistenceUnits.length; i++) {

            URL url = persistenceUnits[i];

    		try {

             nu.xom.Builder b = new nu.xom.Builder(false);

             Document d = b.build(url.openStream());

             Nodes unitNodes = d.getRootElement().query("//p:persistence-unit",  			new XPathContext("p", "http://java.sun.com/xml/ns/persistence"));

             for(int j=0; j < unitNodes.size(); j++) {

             	Node unitNode = unitNodes.get(j);

            	Element unitElt = ((Element)unitNode);

 		String unitName = unitElt.getAttributeValue("name");
		if(!unitName.equals("my-persistence-context"))
          		continue;

 	        Nodes classNodes = unitElt.query("//p:class",  			new XPathContext("p", "http://java.sun.com/xml/ns/persistence"));

 	        for(int k=0; k < classNodes.size(); k++) {

            		Node classNode = classNodes.get(k);

             		if(!(classNode instanceof Element))

             			continue;

         			Element classElt = (Element)classNode;

         			if(!(classElt.getLocalName().equals("class")))

         				continue;

 	            	String className = classNode.getValue();

 	                System.out.println("   class: "+className);

 	            	Class classInstance = Class.forName(className);

 	            	classes.add(classInstance);

 	            }

             }

    		} catch(Exception x) {

    			x.printStackTrace();

    			throw new Error(x);

    		}

        }

        return classes.toArray(new Class[classes.size()]);

 }

This is making use of the “Classpath” utility class from facelets, available here. Also note that you’ll have to replace “my-persistence-context” with your own persistence context name.

This also serves as an example of how to find things in the classpath and configure yourself; I’ve used for my own GWT templating system based on facelets. I used the facelets code to find my own tag libraries, just the way that facelets does. It’s quite a nice model for auto-discovery!

Advertisements

2 Responses to Using persistence.xml and ejb3unit

  1. Daniel Wiese says:

    Hey Dobes,
    i just saw it and would like to integrate this piece into the Ejb3Unit framework, if you don’t mind

    Daniel

  2. dobes says:

    Sounds like a good idea, go for it!

%d bloggers like this: