[hibernate-commits] Hibernate SVN: r10454 - in trunk/HibernateExt: ejb/src/java/org/hibernate/ejb ejb/src/java/org/hibernate/ejb/util metadata/src/java/org/hibernate/cfg

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue Sep 5 20:03:50 EDT 2006


Author: epbernard
Date: 2006-09-05 20:03:49 -0400 (Tue, 05 Sep 2006)
New Revision: 10454

Added:
   trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3ConfigurationObjectFactory.java
   trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/util/NamingHelper.java
Modified:
   trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java
   trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/HibernatePersistence.java
   trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java
Log:
EJB-160 make Ejb3Configuration and AnnotationConfiguration serializable and allow JNDI reference

Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java	2006-09-05 20:38:24 UTC (rev 10453)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java	2006-09-06 00:03:49 UTC (rev 10454)
@@ -2,10 +2,13 @@
 package org.hibernate.ejb;
 
 import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.net.URL;
 import java.util.ArrayList;
@@ -19,6 +22,10 @@
 import java.util.Properties;
 import java.util.Set;
 import java.util.StringTokenizer;
+import javax.naming.BinaryRefAddr;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.Referenceable;
 import javax.persistence.Embeddable;
 import javax.persistence.Entity;
 import javax.persistence.EntityManagerFactory;
@@ -39,8 +46,8 @@
 import org.hibernate.HibernateException;
 import org.hibernate.Interceptor;
 import org.hibernate.MappingException;
+import org.hibernate.MappingNotFoundException;
 import org.hibernate.SessionFactory;
-import org.hibernate.MappingNotFoundException;
 import org.hibernate.cfg.AnnotationConfiguration;
 import org.hibernate.cfg.Configuration;
 import org.hibernate.cfg.Environment;
@@ -55,6 +62,7 @@
 import org.hibernate.ejb.transaction.JoinableCMTTransactionFactory;
 import org.hibernate.ejb.util.ConfigurationHelper;
 import org.hibernate.ejb.util.LogHelper;
+import org.hibernate.ejb.util.NamingHelper;
 import org.hibernate.engine.FilterDefinition;
 import org.hibernate.event.EventListeners;
 import org.hibernate.mapping.AuxiliaryDatabaseObject;
@@ -72,9 +80,23 @@
 import org.xml.sax.SAXException;
 
 /**
+ * Allow a fine tuned configuration of an EJB 3.0 EntityManagerFactory
+ *
+ * A Ejb3Configuration object is only guaranteed to create one EntityManagerFactory.
+ * Multiple usage of #buildEntityManagerFactory() is not guaranteed.
+ *
+ * After #buildEntityManagerFactory() has been called, you no longer can change the configuration
+ * state (no class adding, no property change etc)
+ *
+ * When serialized / deserialized or retrieved from the JNDI, you no longer can change the
+ * configuration state (no class adding, no property change etc)
+ *
+ * Putting the configuration in the JNDI is an expensive operation that requires a partial
+ * serialization
+ *
  * @author Emmanuel Bernard
  */
-public class Ejb3Configuration implements Serializable {
+public class Ejb3Configuration implements Serializable, Referenceable {
 	private static final String IMPLEMENTATION_NAME = HibernatePersistence.class.getName();
 	private static final String META_INF_ORM_XML = "META-INF/orm.xml";
 	private static Log log = LogFactory.getLog( Ejb3Configuration.class );
@@ -85,10 +107,10 @@
 
 	private AnnotationConfiguration cfg;
 	private SettingsFactory settingsFactory;
-	private EventListenerConfigurator listenerConfigurator;
+	private transient EventListenerConfigurator listenerConfigurator;
 	private PersistenceUnitTransactionType transactionType;
 	private boolean discardOnClose;
-	private ClassLoader overridenClassLoader;
+	private transient ClassLoader overridenClassLoader;
 
 
 	public Ejb3Configuration() {
@@ -660,12 +682,13 @@
 			thread.setContextClassLoader( overridenClassLoader );
 		}
 		try {
+			NamingHelper.bind(this);
 			return new EntityManagerFactoryImpl(
 					cfg.buildSessionFactory(),
 					transactionType,
 					discardOnClose
 			);
-			}
+		}
 		catch (HibernateException e) {
 			throw new PersistenceException( e );
 		}
@@ -676,6 +699,32 @@
 		}
 	}
 
+	public Reference getReference() throws NamingException {
+		log.debug("Returning a Reference to the Ejb3Configuration");
+		ByteArrayOutputStream stream = new ByteArrayOutputStream();
+		ObjectOutput out = null;
+		byte[] serialized;
+		try {
+			out = new ObjectOutputStream( stream );
+			out.writeObject( this );
+			out.close();
+			serialized = stream.toByteArray();
+			stream.close();
+		}
+		catch (IOException e) {
+			NamingException namingException = new NamingException( "Unable to serialize Ejb3Configuration" );
+			namingException.setRootCause( e );
+			throw namingException;
+		}
+
+		return new Reference(
+				Ejb3Configuration.class.getName(),
+				new BinaryRefAddr("object", serialized ),
+				Ejb3ConfigurationObjectFactory.class.getName(),
+				null
+		);
+	}
+
 	/**
 	 * create a factory from a canonical workingVars map and the overriden properties
 	 *

Added: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3ConfigurationObjectFactory.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3ConfigurationObjectFactory.java	2006-09-05 20:38:24 UTC (rev 10453)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3ConfigurationObjectFactory.java	2006-09-06 00:03:49 UTC (rev 10454)
@@ -0,0 +1,27 @@
+//$Id: $
+package org.hibernate.ejb;
+
+import java.io.ByteArrayInputStream;
+import java.io.ObjectInputStream;
+import java.util.Hashtable;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.Reference;
+import javax.naming.spi.ObjectFactory;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class Ejb3ConfigurationObjectFactory implements ObjectFactory {
+	public Object getObjectInstance(
+			Object reference, Name name, Context nameCtx, Hashtable<?, ?> environment
+	) throws Exception {
+		byte[] serialized = (byte[]) ( (Reference) reference ).get(0).getContent();
+		ByteArrayInputStream byteIn = new ByteArrayInputStream( serialized );
+		ObjectInputStream in = new ObjectInputStream( byteIn );
+		Ejb3Configuration cfg = (Ejb3Configuration) in.readObject();
+		in.close();
+		byteIn.close();
+		return cfg;
+	}
+}

Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/HibernatePersistence.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/HibernatePersistence.java	2006-09-05 20:38:24 UTC (rev 10453)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/HibernatePersistence.java	2006-09-06 00:03:49 UTC (rev 10454)
@@ -34,21 +34,6 @@
 	 */
 	public static final String AUTODETECTION = "hibernate.archive.autodetection";
 	/**
-	 * List of classes names
-	 * Internal use only
-	 */
-	public static final String CLASS_NAMES = "hibernate.ejb.classes";
-	/**
-	 * List of annotated packages
-	 * Internal use only
-	 */
-	public static final String PACKAGE_NAMES = "hibernate.ejb.packages";
-	/**
-	 * List of classes names
-	 * Internal use only
-	 */
-	public static final String XML_FILE_NAMES = "hibernate.ejb.xml_files";
-	/**
 	 * cfg.xml configuration file used
 	 */
 	public static final String CFG_FILE = "hibernate.ejb.cfgfile";
@@ -86,12 +71,33 @@
 	 * The EJB3 compliant and default choice is false
 	 */
 	public static final String DISCARD_PC_ON_CLOSE = "hibernate.ejb.discard_pc_on_close";
+	/**
+	 * Consider this as experimental
+	 * It is not recommended to set up this property, the configuration is stored
+	 * in the JNDI in a serialized form
+	 */
+	public static final String CONFIGURATION_JNDI_NAME = "hibernate.ejb.configuration_jndi_name";
 
 	//The following properties are for Internal use only
 	/**
 	 * link to the alternative Hibernate configuration file
 	 * Internal use only
 	 */
+	/**
+	 * List of classes names
+	 * Internal use only
+	 */
+	public static final String CLASS_NAMES = "hibernate.ejb.classes";
+	/**
+	 * List of annotated packages
+	 * Internal use only
+	 */
+	public static final String PACKAGE_NAMES = "hibernate.ejb.packages";
+	/**
+	 * List of classes names
+	 * Internal use only
+	 */
+	public static final String XML_FILE_NAMES = "hibernate.ejb.xml_files";
 	public static final String HBXML_FILES = "hibernate.hbmxml.files";
 	public static final String LOADED_CLASSES = "hibernate.ejb.loaded.classes";
 	public static final String JACC_CONTEXT_ID = "hibernate.jacc.ctx.id";

Added: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/util/NamingHelper.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/util/NamingHelper.java	2006-09-05 20:38:24 UTC (rev 10453)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/util/NamingHelper.java	2006-09-06 00:03:49 UTC (rev 10454)
@@ -0,0 +1,74 @@
+//$Id: $
+package org.hibernate.ejb.util;
+
+import javax.naming.Context;
+import javax.naming.InvalidNameException;
+import javax.naming.NamingException;
+import javax.naming.event.EventContext;
+import javax.naming.event.NamespaceChangeListener;
+import javax.naming.event.NamingEvent;
+import javax.naming.event.NamingExceptionEvent;
+import javax.naming.event.NamingListener;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.ejb.Ejb3Configuration;
+import org.hibernate.ejb.HibernatePersistence;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class NamingHelper {
+	private NamingHelper() {};
+
+	private static Log log = LogFactory.getLog( NamingHelper.class );
+
+	/** bind the configuration to the JNDI */
+	public static void bind(Ejb3Configuration cfg) {
+		String name = cfg.getHibernateConfiguration().getProperty( HibernatePersistence.CONFIGURATION_JNDI_NAME );
+		if ( name == null ) {
+			log.debug( "Not Ejb3Configuration to JNDI, no JNDI name configured" );
+		}
+		else {
+			log.info( "Ejb3Configuration name: " + name );
+
+			try {
+				Context ctx = org.hibernate.util.NamingHelper.getInitialContext( cfg.getProperties() );
+				org.hibernate.util.NamingHelper.bind( ctx, name, cfg );
+				log.info( "Bound Ejb3Configuration to JNDI name: " + name );
+				( (EventContext) ctx ).addNamingListener( name, EventContext.OBJECT_SCOPE, LISTENER );
+			}
+			catch (InvalidNameException ine) {
+				log.error( "Invalid JNDI name: " + name, ine );
+			}
+			catch (NamingException ne) {
+				log.warn( "Could not bind Ejb3Configuration to JNDI", ne );
+			}
+			catch (ClassCastException cce) {
+				log.warn( "InitialContext did not implement EventContext" );
+			}
+		}
+	}
+
+	private static final NamingListener LISTENER = new NamespaceChangeListener() {
+		public void objectAdded(NamingEvent evt) {
+			log.debug( "An Ejb3Configuration was successfully bound to name: " + evt.getNewBinding().getName() );
+		}
+
+		public void objectRemoved(NamingEvent evt) {
+			String name = evt.getOldBinding().getName();
+			log.info( "An Ejb3Configuration was unbound from name: " + name );
+		}
+
+		public void objectRenamed(NamingEvent evt) {
+			String name = evt.getOldBinding().getName();
+			log.info( "An Ejb3Configuration was renamed from name: " + name );
+		}
+
+		public void namingExceptionThrown(NamingExceptionEvent evt) {
+			log.warn( "Naming exception occurred accessing Ejb3Configuration: " + evt.getException() );
+		}
+	};
+
+
+}

Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java	2006-09-05 20:38:24 UTC (rev 10453)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java	2006-09-06 00:03:49 UTC (rev 10454)
@@ -80,7 +80,7 @@
 	private List<Document> hbmDocuments; //user ordering matters, hence the list
 	private String precedence = null;
 	private boolean inSecondPass = false;
-	private ReflectionManager reflectionManager;
+	private transient ReflectionManager reflectionManager;
 	private boolean isDefaultProcessed = false;
 
 	public AnnotationConfiguration() {




More information about the hibernate-commits mailing list