Browse Source

More fetching/initialization related fine-tuning.

Ben Alex 20 years ago
parent
commit
307cd35b9c

+ 53 - 0
domain/src/main/java/org/acegisecurity/domain/dao/Dao.java

@@ -161,6 +161,35 @@ public interface Dao<E extends PersistableEntity> {
     public PaginatedList<E> scroll(E value, int firstElement,
         int maxElements, String orderByAsc);
 
+    /**
+     * Find persistent instances with properties matching those of the passed
+     * <code>PersistableEntity</code>, with a guarantee the returned results
+     * will have each of the <code>value</code> class' immediate properties
+     * initialized.
+     * 
+     * <P>
+     * Persistent instances are matched on the basis of query by example.
+     * Properties whose value is <code>null</code>, empty
+     * <code>String</code>s, and any <code>Collection</code>s are ignored in
+     * the query by example evaluation.
+     * </p>
+     *
+     * @param value parameters to filter on (the class of this object will
+     * be added to the filter)
+     * @param firstElement the first result (start at zero to obtain all
+     *        results)
+     * @param maxElements the maximum number of results desired for this page
+     *        of the result set
+     * @param orderByAsc the property name of the
+     *        <code>PersistableEntity</code> that should be used to order the
+     *        results
+     *
+     * @return the requested page of the result list (a properly formed
+     *         <code>PaginatedList</code> is returned if no results match)
+     */
+    public PaginatedList<E> scrollPopulated(E value, int firstElement,
+        int maxElements, String orderByAsc);
+
 	/**
      * Find persistent instances with properties matching those of the passed
      * <code>PersistableEntity</code>, ignoring the class of the passed
@@ -183,6 +212,30 @@ public interface Dao<E extends PersistableEntity> {
     public PaginatedList<E> scrollWithSubclasses(E value, int firstElement,
 	        int maxElements, String orderByAsc);
 
+	/**
+     * Find persistent instances with properties matching those of the passed
+     * <code>PersistableEntity</code>, ignoring the class of the passed
+     * <code>PersistableEntity</code> (useful if you pass a superclass, as you
+     * want to find all subclass instances which match). Guarantees the returned 
+     * results will have each of the DAO's <code>supports</code> class' immediate
+     * properties initialized.
+	 * 
+     * @param value parameters to filter on (the class of this object will
+     * NOT be added to the filter)
+     * @param firstElement the first result (start at zero to obtain all
+     *        results)
+     * @param maxElements the maximum number of results desired for this page
+     *        of the result set
+     * @param orderByAsc the property name of the
+     *        <code>PersistableEntity</code> that should be used to order the
+     *        results
+     *
+     * @return the requested page of the result list (a properly formed
+     *         <code>PaginatedList</code> is returned if no results match)
+	 */
+    public PaginatedList<E> scrollPopulatedWithSubclasses(E value, int firstElement,
+	        int maxElements, String orderByAsc);
+
 	/**
      * Indicates whether the DAO instance provides persistence services for the
      * specified class.

+ 9 - 0
domain/src/main/java/org/acegisecurity/domain/dao/InitializationCapable.java

@@ -72,4 +72,13 @@ public interface InitializationCapable {
      * @param entity to initialize
      */
     public void initialize(Object entity);
+	
+	/**
+	 * Indicaets whether the passed object is initialized or not.
+	 * 
+	 * @param entity to determine if initialized
+	 * @return <code>true</code> if initialized, <code>false</code> is uninitialized or
+	 * 		   the initialization status is unknown
+	 */
+	public boolean isInitialized(Object entity);
 }

+ 18 - 1
domain/src/main/java/org/acegisecurity/domain/dao/InitializationUtils.java

@@ -46,5 +46,22 @@ public class InitializationUtils {
 			((InitializationCapable) daoOrServices).initialize(entity);
 		}
     }
-
+	
+	/**
+	 * Indicates whether the passed entity has been initialized, by delegating
+	 * to the passed daoOrServices (provided that the passed daoOrServices
+	 * implements <code>InitializationCapable</code>.
+	 * 
+	 * @param entity to determine whether initialized or not
+	 * @return <code>true</code> if initialized, <code>false</code> if it is
+	 * 			uninitialized or the passed daoOrServices does not provide
+	 * 			initialization querying support
+	 */
+	public static boolean isInitialized(Object daoOrServices, Object entity) {
+		Assert.notNull(daoOrServices);
+		if (daoOrServices instanceof InitializationCapable) {
+			return ((InitializationCapable) daoOrServices).isInitialized(entity);
+		}
+		return false;
+	}
 }

+ 39 - 13
domain/src/main/java/org/acegisecurity/domain/hibernate/DaoHibernate.java

@@ -29,6 +29,7 @@ import net.sf.acegisecurity.domain.validation.ValidationManager;
 
 import org.hibernate.Criteria;
 import org.hibernate.EntityMode;
+import org.hibernate.FetchMode;
 import org.hibernate.Hibernate;
 import org.hibernate.HibernateException;
 import org.hibernate.Session;
@@ -164,26 +165,39 @@ public class DaoHibernate<E extends PersistableEntity> extends HibernateDaoSuppo
 	
     public PaginatedList<E> scroll(E value, int firstElement,
         int maxElements, String orderByAsc) {
-        Assert.notNull(value);
-        Assert.hasText(orderByAsc,
-            "An orderByAsc is required (why not use your identity property?)");
-		Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this DAO supports");
-
+		validateScrollMethod(value, firstElement, maxElements, orderByAsc);
         return (PaginatedList) getHibernateTemplate().execute(getFindByValueCallback(
-                value.getClass(), value, firstElement, maxElements, Order.asc(orderByAsc)));
+                value.getClass(), false, value, firstElement, maxElements, Order.asc(orderByAsc)));
     }
 
     public PaginatedList<E> scrollWithSubclasses(E value, int firstElement,
 	        int maxElements, String orderByAsc) {
-	        Assert.notNull(value);
-	        Assert.hasText(orderByAsc,
-	            "An orderByAsc is required (why not use your identity property?)");
-			Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this DAO supports");
-
+			validateScrollMethod(value, firstElement, maxElements, orderByAsc);
+	        return (PaginatedList) getHibernateTemplate().execute(getFindByValueCallback(
+	                this.supportsClass, false, value, firstElement, maxElements, Order.asc(orderByAsc)));
+	    }
+	
+    public PaginatedList<E> scrollPopulated(E value, int firstElement,
+	        int maxElements, String orderByAsc) {
+			validateScrollMethod(value, firstElement, maxElements, orderByAsc);
 	        return (PaginatedList) getHibernateTemplate().execute(getFindByValueCallback(
-	                this.supportsClass, value, firstElement, maxElements, Order.asc(orderByAsc)));
+	                value.getClass(), true, value, firstElement, maxElements, Order.asc(orderByAsc)));
 	    }
 
+	public PaginatedList<E> scrollPopulatedWithSubclasses(E value, int firstElement,
+		        int maxElements, String orderByAsc) {
+				validateScrollMethod(value, firstElement, maxElements, orderByAsc);
+		        return (PaginatedList) getHibernateTemplate().execute(getFindByValueCallback(
+		                this.supportsClass, true, value, firstElement, maxElements, Order.asc(orderByAsc)));
+		    }
+
+	private void validateScrollMethod(E value, int firstElement, int MaxElements, String orderByAsc) {
+        Assert.notNull(value);
+        Assert.hasText(orderByAsc,
+            "An orderByAsc is required (why not use your identity property?)");
+		Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this DAO supports");
+	}
+
 	public boolean supports(Class clazz) {
         Assert.notNull(clazz);
 
@@ -223,6 +237,10 @@ public class DaoHibernate<E extends PersistableEntity> extends HibernateDaoSuppo
 		Hibernate.initialize(entity);
 	}
 
+	public boolean isInitialized(Object entity) {
+		return Hibernate.isInitialized(entity);
+	}
+
 	/**
      * Provides a <code>HibernateCallback</code> that will load a list of
      * objects by a <code>Collection</code> of identities.
@@ -256,6 +274,9 @@ public class DaoHibernate<E extends PersistableEntity> extends HibernateDaoSuppo
      * the "version" name. If the property is mapped as String find a partial
      * match, otherwise find by exact match.
      *
+     * @param whichClass the class (and subclasses) which results will be limited to including
+     * @param initializeAllProperties indicates whether lazy initialized properties
+     *        should be initialized in the returned results
      * @param bean bean with the values of the parameters
      * @param firstElement the first result, numbered from 0
      * @param count the maximum number of results
@@ -263,7 +284,7 @@ public class DaoHibernate<E extends PersistableEntity> extends HibernateDaoSuppo
      *
      * @return a PaginatedList containing the requested objects
      */
-    private HibernateCallback getFindByValueCallback(final Class whichClass, final Object bean,
+    private HibernateCallback getFindByValueCallback(final Class whichClass, final boolean initializeAllProperties, final Object bean,
         final int firstElement, final int count, final Order order) {
         return new HibernateCallback() {
                 public Object doInHibernate(Session session)
@@ -286,6 +307,11 @@ public class DaoHibernate<E extends PersistableEntity> extends HibernateDaoSuppo
                     for (int i = 0; i < propertyNames.length; i++) {
                         String name = propertyNames[i];
                         
+						// Indicate preferred fetching here
+						if (initializeAllProperties) {
+							criteria.setFetchMode(name, FetchMode.JOIN);
+						}
+						
                         // TODO: Check if EntityMode.POJO appropriate
                         Object value = classMetadata.getPropertyValue(bean, name, EntityMode.POJO);
 

+ 47 - 0
domain/src/main/java/org/acegisecurity/domain/service/Manager.java

@@ -175,6 +175,32 @@ public interface Manager<E extends PersistableEntity> {
     public PaginatedList<E> scroll(E value, int firstElement,
         int maxElements);
 
+    /**
+     * Find persistent instances with properties matching those of the passed
+     * <code>PersistableEntity</code>, with a guarantee the returned results
+     * will have each of the <code>value</code> class' immediate properties
+     * initialized.
+     * 
+     * <P>
+     * Persistent instances are matched on the basis of query by example.
+     * Properties whose value is <code>null</code>, empty
+     * <code>String</code>s, and any <code>Collection</code>s are ignored in
+     * the query by example evaluation.
+     * </p>
+     *
+     * @param value parameters to filter on (the class of this object will
+     * be added to the filter)
+     * @param firstElement the first result (start at zero to obtain all
+     *        results)
+     * @param maxElements the maximum number of results desired for this page
+     *        of the result set
+     *
+     * @return the requested page of the result list (a properly formed
+     *         <code>PaginatedList</code> is returned if no results match)
+     */
+    public PaginatedList<E> scrollPopulated(E value, int firstElement,
+        int maxElements);
+
 	/**
      * Find persistent instances with properties matching those of the passed
      * <code>PersistableEntity</code>, ignoring the class of the passed
@@ -194,6 +220,27 @@ public interface Manager<E extends PersistableEntity> {
     public PaginatedList<E> scrollWithSubclasses(E value, int firstElement,
 	        int maxElements);
 
+	/**
+     * Find persistent instances with properties matching those of the passed
+     * <code>PersistableEntity</code>, ignoring the class of the passed
+     * <code>PersistableEntity</code> (useful if you pass a superclass, as you
+     * want to find all subclass instances which match). Guarantees the returned 
+     * results will have each of the DAO's <code>supports</code> class' immediate
+     * properties initialized.
+	 * 
+     * @param value parameters to filter on (the class of this object will
+     * NOT be added to the filter)
+     * @param firstElement the first result (start at zero to obtain all
+     *        results)
+     * @param maxElements the maximum number of results desired for this page
+     *        of the result set
+     *
+     * @return the requested page of the result list (a properly formed
+     *         <code>PaginatedList</code> is returned if no results match)
+	 */
+    public PaginatedList<E> scrollPopulatedWithSubclasses(E value, int firstElement,
+	        int maxElements);
+	
 	/**
      * Indicates whether the DAO instance provides persistence services for the
      * specified class.

+ 15 - 1
domain/src/main/java/org/acegisecurity/domain/service/ManagerImpl.java

@@ -136,7 +136,14 @@ public class ManagerImpl<E extends PersistableEntity> extends ApplicationObjectS
         return dao.scroll(value, firstElement, maxElements, getDefaultSortOrder());
     }
 
-    public PaginatedList<E> scrollWithSubclasses(E value, int firstElement,
+    public PaginatedList<E> scrollPopulated(E value, int firstElement, int maxElements) {
+        Assert.notNull(value);
+		Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this manager supports");
+		
+		return dao.scrollPopulated(value, firstElement, maxElements, getDefaultSortOrder());
+	}
+
+	public PaginatedList<E> scrollWithSubclasses(E value, int firstElement,
 	        int maxElements) {
 	        Assert.notNull(value);
 			Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this manager supports");
@@ -144,6 +151,13 @@ public class ManagerImpl<E extends PersistableEntity> extends ApplicationObjectS
 	        return dao.scrollWithSubclasses(value, firstElement, maxElements, getDefaultSortOrder());
 	    }
 
+	public PaginatedList<E> scrollPopulatedWithSubclasses(E value, int firstElement, int maxElements) {
+        Assert.notNull(value);
+		Assert.isInstanceOf(this.supportsClass, value, "Can only scroll with values this manager supports");
+
+		return dao.scrollPopulatedWithSubclasses(value, firstElement, maxElements, getDefaultSortOrder());
+	}
+
 	public boolean supports(Class clazz) {
         Assert.notNull(clazz);