From 307cd35b9c1357865f08d17e6941b7746d230804 Mon Sep 17 00:00:00 2001 From: Ben Alex Date: Sat, 14 May 2005 01:35:13 +0000 Subject: [PATCH] More fetching/initialization related fine-tuning. --- .../org/acegisecurity/domain/dao/Dao.java | 53 +++++++++++++++++++ .../domain/dao/InitializationCapable.java | 9 ++++ .../domain/dao/InitializationUtils.java | 19 ++++++- .../domain/hibernate/DaoHibernate.java | 52 +++++++++++++----- .../acegisecurity/domain/service/Manager.java | 47 ++++++++++++++++ .../domain/service/ManagerImpl.java | 16 +++++- 6 files changed, 181 insertions(+), 15 deletions(-) diff --git a/domain/src/main/java/org/acegisecurity/domain/dao/Dao.java b/domain/src/main/java/org/acegisecurity/domain/dao/Dao.java index fd524624ab..3c4058f39b 100644 --- a/domain/src/main/java/org/acegisecurity/domain/dao/Dao.java +++ b/domain/src/main/java/org/acegisecurity/domain/dao/Dao.java @@ -161,6 +161,35 @@ public interface Dao { public PaginatedList scroll(E value, int firstElement, int maxElements, String orderByAsc); + /** + * Find persistent instances with properties matching those of the passed + * PersistableEntity, with a guarantee the returned results + * will have each of the value class' immediate properties + * initialized. + * + *

+ * Persistent instances are matched on the basis of query by example. + * Properties whose value is null, empty + * Strings, and any Collections are ignored in + * the query by example evaluation. + *

+ * + * @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 + * PersistableEntity that should be used to order the + * results + * + * @return the requested page of the result list (a properly formed + * PaginatedList is returned if no results match) + */ + public PaginatedList scrollPopulated(E value, int firstElement, + int maxElements, String orderByAsc); + /** * Find persistent instances with properties matching those of the passed * PersistableEntity, ignoring the class of the passed @@ -183,6 +212,30 @@ public interface Dao { public PaginatedList scrollWithSubclasses(E value, int firstElement, int maxElements, String orderByAsc); + /** + * Find persistent instances with properties matching those of the passed + * PersistableEntity, ignoring the class of the passed + * PersistableEntity (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 supports 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 + * PersistableEntity that should be used to order the + * results + * + * @return the requested page of the result list (a properly formed + * PaginatedList is returned if no results match) + */ + public PaginatedList scrollPopulatedWithSubclasses(E value, int firstElement, + int maxElements, String orderByAsc); + /** * Indicates whether the DAO instance provides persistence services for the * specified class. diff --git a/domain/src/main/java/org/acegisecurity/domain/dao/InitializationCapable.java b/domain/src/main/java/org/acegisecurity/domain/dao/InitializationCapable.java index de5fba165c..0f01b5e053 100644 --- a/domain/src/main/java/org/acegisecurity/domain/dao/InitializationCapable.java +++ b/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 true if initialized, false is uninitialized or + * the initialization status is unknown + */ + public boolean isInitialized(Object entity); } diff --git a/domain/src/main/java/org/acegisecurity/domain/dao/InitializationUtils.java b/domain/src/main/java/org/acegisecurity/domain/dao/InitializationUtils.java index 0e4cf2dac6..e90ad4a705 100644 --- a/domain/src/main/java/org/acegisecurity/domain/dao/InitializationUtils.java +++ b/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 InitializationCapable. + * + * @param entity to determine whether initialized or not + * @return true if initialized, false 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; + } } diff --git a/domain/src/main/java/org/acegisecurity/domain/hibernate/DaoHibernate.java b/domain/src/main/java/org/acegisecurity/domain/hibernate/DaoHibernate.java index 752fdc2897..17056be970 100644 --- a/domain/src/main/java/org/acegisecurity/domain/hibernate/DaoHibernate.java +++ b/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,25 +165,38 @@ public class DaoHibernate extends HibernateDaoSuppo public PaginatedList 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 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, value, firstElement, maxElements, Order.asc(orderByAsc))); + this.supportsClass, false, value, firstElement, maxElements, Order.asc(orderByAsc))); } + + public PaginatedList scrollPopulated(E value, int firstElement, + int maxElements, String orderByAsc) { + validateScrollMethod(value, firstElement, maxElements, orderByAsc); + return (PaginatedList) getHibernateTemplate().execute(getFindByValueCallback( + value.getClass(), true, value, firstElement, maxElements, Order.asc(orderByAsc))); + } + + public PaginatedList 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 extends HibernateDaoSuppo Hibernate.initialize(entity); } + public boolean isInitialized(Object entity) { + return Hibernate.isInitialized(entity); + } + /** * Provides a HibernateCallback that will load a list of * objects by a Collection of identities. @@ -256,6 +274,9 @@ public class DaoHibernate 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 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 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); diff --git a/domain/src/main/java/org/acegisecurity/domain/service/Manager.java b/domain/src/main/java/org/acegisecurity/domain/service/Manager.java index 9e6992c396..0f493bc02d 100644 --- a/domain/src/main/java/org/acegisecurity/domain/service/Manager.java +++ b/domain/src/main/java/org/acegisecurity/domain/service/Manager.java @@ -175,6 +175,32 @@ public interface Manager { public PaginatedList scroll(E value, int firstElement, int maxElements); + /** + * Find persistent instances with properties matching those of the passed + * PersistableEntity, with a guarantee the returned results + * will have each of the value class' immediate properties + * initialized. + * + *

+ * Persistent instances are matched on the basis of query by example. + * Properties whose value is null, empty + * Strings, and any Collections are ignored in + * the query by example evaluation. + *

+ * + * @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 + * PaginatedList is returned if no results match) + */ + public PaginatedList scrollPopulated(E value, int firstElement, + int maxElements); + /** * Find persistent instances with properties matching those of the passed * PersistableEntity, ignoring the class of the passed @@ -194,6 +220,27 @@ public interface Manager { public PaginatedList scrollWithSubclasses(E value, int firstElement, int maxElements); + /** + * Find persistent instances with properties matching those of the passed + * PersistableEntity, ignoring the class of the passed + * PersistableEntity (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 supports 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 + * PaginatedList is returned if no results match) + */ + public PaginatedList scrollPopulatedWithSubclasses(E value, int firstElement, + int maxElements); + /** * Indicates whether the DAO instance provides persistence services for the * specified class. diff --git a/domain/src/main/java/org/acegisecurity/domain/service/ManagerImpl.java b/domain/src/main/java/org/acegisecurity/domain/service/ManagerImpl.java index 7ca6c82979..a0d6a1df9b 100644 --- a/domain/src/main/java/org/acegisecurity/domain/service/ManagerImpl.java +++ b/domain/src/main/java/org/acegisecurity/domain/service/ManagerImpl.java @@ -136,7 +136,14 @@ public class ManagerImpl extends ApplicationObjectS return dao.scroll(value, firstElement, maxElements, getDefaultSortOrder()); } - public PaginatedList scrollWithSubclasses(E value, int firstElement, + public PaginatedList 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 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 extends ApplicationObjectS return dao.scrollWithSubclasses(value, firstElement, maxElements, getDefaultSortOrder()); } + public PaginatedList 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);