diff --git a/domain/src/main/java/org/acegisecurity/domain/PersistableEntity.java b/domain/src/main/java/org/acegisecurity/domain/PersistableEntity.java
index 9726bbfcf6..65ec93ca50 100644
--- a/domain/src/main/java/org/acegisecurity/domain/PersistableEntity.java
+++ b/domain/src/main/java/org/acegisecurity/domain/PersistableEntity.java
@@ -52,5 +52,5 @@ public interface PersistableEntity {
*
* @return the persistence identity of this instance
*/
- abstract Serializable getInternalId();
+ public abstract Serializable getInternalId();
}
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 42b69fa80c..58a8a27fe2 100644
--- a/domain/src/main/java/org/acegisecurity/domain/dao/Dao.java
+++ b/domain/src/main/java/org/acegisecurity/domain/dao/Dao.java
@@ -15,13 +15,13 @@
package org.acegisecurity.domain.dao;
-import org.acegisecurity.domain.PersistableEntity;
-
import java.io.Serializable;
-
import java.util.Collection;
import java.util.List;
+import org.acegisecurity.domain.PersistableEntity;
+import org.springframework.dao.DataAccessException;
+
/**
* Provides fundamental DAO capabilities for a single concrete {@link
* PersistableEntity}, using JDK 1.5 generics.
@@ -44,9 +44,7 @@ import java.util.List;
* be the sole entry point into the persistance layer of an application. The
* persistence layer should only respond to requests from the services layer.
* The services layer is where all transaction demarcation, security
- * authorization, casting to and from concrete {@link
- * org.acegisecurity.domain.PersistableEntity}s, workflow and business
- * logic should take place.
+ * authorization, workflow and business logic should take place.
*
*
*
@@ -67,17 +65,15 @@ public interface Dao {
* PersistableEntity#getInternalId()} value being ignored.
*
* @param value (without the identity property initialized)
- *
- * @return the value created (with the identity property initialised)
*/
- public E create(E value);
+ public void create(E value) throws DataAccessException;
/**
* Delete an object.
*
* @param value the value to delete
*/
- public void delete(E value);
+ public void delete(E value) throws DataAccessException;
/**
* Return all persistent instances, including subclasses.
@@ -85,7 +81,7 @@ public interface Dao {
* @return all persistence instances (an empty List
will be
* returned if no matches are found)
*/
- public List findAll();
+ public List findAll() throws DataAccessException;
/**
* Find a List
of PersistableEntity
s, searched by
@@ -96,7 +92,7 @@ public interface Dao {
* @return the values with those identifiers (an empty List
* will be returned if no matches are found)
*/
- public List findId(Collection ids);
+ public List findId(Collection ids) throws DataAccessException;
/**
* Load a persistent instance by its identifier, although some properties
@@ -108,19 +104,8 @@ public interface Dao {
*
* @return the request item, or null
if not found
*/
- public E readId(Serializable id);
+ public E readId(Serializable id) throws DataAccessException;
- /**
- * Loads a persistent instance by its identifier, along with any
- * lazy loaded properties associated with that instance.
- *
- * @param id the identifier of the persistent instance desired to be
- * retrieved
- *
- * @return the request item, or null
if not found
- */
- public E readPopulatedId(Serializable id);
-
/**
* Find persistent instances with properties matching those of the passed
* PersistableEntity
.
@@ -146,36 +131,7 @@ public interface Dao {
* PaginatedList
is returned if no results match)
*/
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
- * String
s, and any Collection
s 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);
+ int maxElements, String orderByAsc) throws DataAccessException;
/**
* Find persistent instances with properties matching those of the passed
@@ -197,31 +153,7 @@ public interface Dao {
* PaginatedList
is returned if no results match)
*/
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);
+ int maxElements, String orderByAsc) throws DataAccessException;
/**
* Indicates whether the DAO instance provides persistence services for the
@@ -240,8 +172,6 @@ public interface Dao {
*
* @param value to update, with the PersistableEntity
having a
* non-null
identifier
- *
- * @return the updated value
*/
- public E update(E value);
+ public void update(E value) throws DataAccessException;
}
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 8099ffdbc6..a98e785510 100644
--- a/domain/src/main/java/org/acegisecurity/domain/hibernate/DaoHibernate.java
+++ b/domain/src/main/java/org/acegisecurity/domain/hibernate/DaoHibernate.java
@@ -16,36 +16,26 @@
package org.acegisecurity.domain.hibernate;
import java.io.Serializable;
-import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import org.acegisecurity.domain.PersistableEntity;
import org.acegisecurity.domain.dao.Dao;
-import org.acegisecurity.domain.dao.DetachmentContextHolder;
-import org.acegisecurity.domain.dao.EvictionCapable;
-import org.acegisecurity.domain.dao.InitializationCapable;
import org.acegisecurity.domain.dao.PaginatedList;
import org.acegisecurity.domain.util.GenericsUtils;
-import org.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;
+import org.hibernate.SessionFactory;
import org.hibernate.criterion.Expression;
-import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.type.Type;
-import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.orm.hibernate3.HibernateCallback;
-import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.util.Assert;
-import org.springframework.validation.BindException;
/**
@@ -55,180 +45,65 @@ import org.springframework.validation.BindException;
* @author Matthew Porter
* @version $Id$
*/
-public class DaoHibernate extends HibernateDaoSupport implements Dao,
- EvictionCapable, InitializationCapable {
+public class DaoHibernate extends HibernateDaoSupport implements Dao {
//~ Instance fields ========================================================
/** The class that this instance provides services for */
private Class supportsClass;
-
- /** Enables mutator methods to validate an object prior to persistence */
- private ValidationManager validationManager;
- public DaoHibernate() {
+ public DaoHibernate(SessionFactory sessionFactory) {
+ Assert.notNull(sessionFactory, "Non-null Hibernate SessionFactory must be expressed as a constructor argument");
+ super.setSessionFactory(sessionFactory);
this.supportsClass = GenericsUtils.getGeneric(getClass());
- if (this.supportsClass == null) {
- if (logger.isWarnEnabled()) {
- logger.warn("Could not determine the generics type - you will need to set manually");
- }
- }
+ Assert.notNull(this.supportsClass, "Could not determine the generics type");
}
//~ Methods ================================================================
- /**
- * Obtains a HibernateTemplate
that uses the appropriate Session
- * based on the value of {@link DetachmentContextHolder}.
- *
- * Specifically, if DetachmentContextHolder
requires detached instances,
- * the method will build a new Session
(ignore the current thread-bound
- * Session
) and use that new Session
in the HibernateTemplate
.
- * If DetachmentContextHolder
is at its fault false
value, the
- * returned HibernateTemplate
will simply use the Session
obtained
- * from the superclass, which is generally the same Session
as used for the
- * transaction.
- *
- * @return the template, containing the correct Session
based on the
- * DetachmentContactHolder
request
- */
- protected HibernateTemplate doGetHibernateTemplate() {
- if (DetachmentContextHolder.isForceReturnOfDetachedInstances()) {
- HibernateTemplate hibernateTemplate = new HibernateTemplate(getSessionFactory());
- hibernateTemplate.setAlwaysUseNewSession(true);
- return hibernateTemplate;
- } else {
- return super.getHibernateTemplate();
- }
- }
-
- public void setSupportsClass(Class supportClass) {
- this.supportsClass = supportClass;
- }
-
- public Class getSupportsClass() {
- return supportsClass;
- }
-
- public ValidationManager getValidationManager() {
- return validationManager;
- }
-
- public void setValidationManager(ValidationManager validationManager) {
- this.validationManager = validationManager;
- }
-
- public E create(E value) {
+ public void create(E value) {
Assert.notNull(value);
- validate(value);
- doGetHibernateTemplate().save(value);
-
- return readId(value.getInternalId());
+ super.getHibernateTemplate().save(value);
}
-
- protected void validate(E value) throws DataIntegrityViolationException {
- try {
- validationManager.validate(value);
- } catch (BindException bindException) {
- throw new DataIntegrityViolationException("Entity state is invalid", bindException);
- }
- }
public void delete(E value) {
Assert.notNull(value);
- validate(value);
- doGetHibernateTemplate().delete(value);
+ super.getHibernateTemplate().delete(value);
}
- public void evict(PersistableEntity entity) {
- Assert.notNull(entity);
- doGetHibernateTemplate().evict(entity);
+ @SuppressWarnings("unchecked")
+ public List findAll() {
+ return super.getHibernateTemplate().loadAll(supportsClass);
}
- public List findAll() {
- return doGetHibernateTemplate().loadAll(supportsClass);
- }
-
- public List findId(Collection ids) {
+ @SuppressWarnings("unchecked")
+ public List findId(Collection ids) {
Assert.notNull(ids, "Collection of IDs cannot be null");
Assert.notEmpty(ids, "There must be some values in the Collection list");
- return (List) doGetHibernateTemplate().execute(getFindByIdCallback(ids));
+ return (List) super.getHibernateTemplate().execute(getFindByIdCallback(ids));
}
- private E readId(final Serializable id, final boolean populate) {
+ @SuppressWarnings("unchecked")
+ public E readId(Serializable id) {
Assert.notNull(id);
- return (E) doGetHibernateTemplate().execute(new HibernateCallback() {
- public Object doInHibernate(Session session) throws HibernateException {
- E obj = (E) session.get(supportsClass, id);
- if (populate) {
- initializeAllZeroArgumentGetters(obj);
- }
- return obj;
- }
- }, true);
+ return (E) getHibernateTemplate().load(supportsClass, id);
}
- public E readId(Serializable id) {
- Assert.notNull(id);
- return readId(id, false);
- }
-
- public E readPopulatedId(Serializable id) {
- Assert.notNull(id);
- return readId(id, true);
- }
-
- /**
- * Locates every get*()
method against the passed entity
- * and calls it. This method does not nest its initialization beyond
- * the immediately passed entity.
- *
- * For example, a Foo object might provide a getBar() method.
- * Passing the Foo instance to this method will guarantee getBar() is
- * available to the services layer. However, if getBar() returned a Bar
- * which in turn provided a getCar() method, there is NO GUARANTEE
- * the getCar() method will be initialized.
- *
- * @param entity for which its immediate getters should be initialized
- */
- protected void initializeAllZeroArgumentGetters(E entity) {
- Method[] methods = entity.getClass().getMethods();
- for (int i = 0; i < methods.length; i++) {
- if (methods[i].getName().startsWith("get") && methods[i].getParameterTypes().length == 0) {
- try {
- Hibernate.initialize(methods[i].invoke(entity, new Object[] {}));
- } catch (Exception ignored) {}
- }
- }
- }
-
- public PaginatedList scroll(E value, int firstElement,
+ @SuppressWarnings("unchecked")
+ public PaginatedList scroll(E value, int firstElement,
int maxElements, String orderByAsc) {
validateScrollMethod(value, firstElement, maxElements, orderByAsc);
- return (PaginatedList) doGetHibernateTemplate().execute(getFindByValueCallback(
- value.getClass(), false, value, firstElement, maxElements, Order.asc(orderByAsc)));
+ return (PaginatedList) super.getHibernateTemplate().execute(getFindByValueCallback(
+ value.getClass(), value, firstElement, maxElements, Order.asc(orderByAsc)));
}
- public PaginatedList scrollWithSubclasses(E value, int firstElement,
+ @SuppressWarnings("unchecked")
+ public PaginatedList scrollWithSubclasses(E value, int firstElement,
int maxElements, String orderByAsc) {
validateScrollMethod(value, firstElement, maxElements, orderByAsc);
- return (PaginatedList) doGetHibernateTemplate().execute(getFindByValueCallback(
- this.supportsClass, false, value, firstElement, maxElements, Order.asc(orderByAsc)));
+ return (PaginatedList) super.getHibernateTemplate().execute(getFindByValueCallback(
+ this.supportsClass, value, firstElement, maxElements, Order.asc(orderByAsc)));
}
-
- public PaginatedList scrollPopulated(E value, int firstElement,
- int maxElements, String orderByAsc) {
- validateScrollMethod(value, firstElement, maxElements, orderByAsc);
- return (PaginatedList) doGetHibernateTemplate().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) doGetHibernateTemplate().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);
@@ -239,46 +114,14 @@ public class DaoHibernate extends HibernateDaoSuppo
public boolean supports(Class clazz) {
Assert.notNull(clazz);
-
return this.supportsClass.equals(clazz);
}
- public E update(E value) {
+ public void update(E value) {
Assert.notNull(value);
- validate(value);
- doGetHibernateTemplate().update(value);
-
- return readId(value.getInternalId());
+ super.getHibernateTemplate().update(value);
}
- /**
- * Custom initialization behavior. Called by superclass.
- *
- * @throws Exception if initialization fails
- */
- protected final void initDao() throws Exception {
- Assert.notNull(supportsClass, "supportClass is required");
- Assert.notNull(validationManager, "validationManager is required");
- Assert.isTrue(PersistableEntity.class.isAssignableFrom(supportsClass), "supportClass is not an implementation of PersistableEntity");
- initHibernateDao();
- }
-
- /**
- * Allows subclasses to provide custom initialization behaviour. Called
- * during {@link #initDao()}.
- *
- * @throws Exception
- */
- protected void initHibernateDao() throws Exception {}
-
- public void initialize(Object entity) {
- 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.
@@ -313,8 +156,6 @@ public class DaoHibernate extends HibernateDaoSuppo
* 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
@@ -322,15 +163,16 @@ public class DaoHibernate extends HibernateDaoSuppo
*
* @return a PaginatedList containing the requested objects
*/
- private HibernateCallback getFindByValueCallback(final Class whichClass, final boolean initializeAllProperties, final Object bean,
- final int firstElement, final int count, final Order order) {
+ private HibernateCallback getFindByValueCallback(final Class whichClass, final Object bean, final int firstElement, final int count, final Order order) {
return new HibernateCallback() {
- public Object doInHibernate(Session session)
+ @SuppressWarnings("unchecked")
+ public Object doInHibernate(Session session)
throws HibernateException {
- Criteria criteria = session.createCriteria(whichClass);
-
- criteria.addOrder(order);
-
+ int paramCount = 0;
+
+ StringBuffer queryString = new StringBuffer("from ").append(bean.getClass().getName()).append(" as queryTarget");
+
+
ClassMetadata classMetadata = getSessionFactory()
.getClassMetadata(bean
.getClass());
@@ -344,12 +186,6 @@ public class DaoHibernate extends HibernateDaoSuppo
/* for each persistent property of the bean */
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);
@@ -371,35 +207,47 @@ public class DaoHibernate extends HibernateDaoSuppo
continue;
}
- Type type = classMetadata.getPropertyType(name);
-
if (name.equals("version")) {
continue;
}
-
- if (name.equals("lastUpdatedUsername") || name.equals("lastUpdatedDate")) {
- continue;
- }
- if (type.equals(Hibernate.STRING)) {
+ Type type = classMetadata.getPropertyType(name);
+
+ if (type.equals(Hibernate.STRING)) {
// if the property is mapped as String, find partial match
- criteria.add(Expression.ilike(name,
- value.toString(), MatchMode.ANYWHERE));
+ if (paramCount == 0) {
+ queryString.append(" where ");
+ } else {
+ queryString.append(" and ");
+ }
+ paramCount++;
+ queryString.append("lower(queryTarget.").append(name).append(") like '%" + value.toString().toLowerCase() + "%'");
} else {
// find exact match
- criteria.add(Expression.eq(name, value));
+ if (paramCount == 0) {
+ queryString.append(" where ");
+ } else {
+ queryString.append(" and ");
+ }
+ paramCount++;
+ queryString.append("queryTarget.").append(name).append(" = " + value);
}
}
-
- /*
- * TODO Use Criteria.count() when available in next Hibernate
- * versions
- */
- int size = criteria.list().size();
-
- List list = criteria.setFirstResult(firstElement).setMaxResults(count).list();
-
- return new PaginatedList(list, firstElement, count, size);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug(queryString.toString());
+ }
+
+ // Determine number of rows
+ org.hibernate.Query countQuery = session.createQuery("select count(*) " + queryString.toString());
+ int size = ((Integer) countQuery.iterate().next()).intValue();
+
+ // Obtain requested page of query
+ org.hibernate.Query query = session.createQuery(queryString.toString());
+ query.setMaxResults(count);
+ query.setFirstResult(firstElement);
+
+ return new PaginatedList(query.list(), firstElement, count, size);
}
};
}
diff --git a/domain/src/main/java/org/acegisecurity/domain/hibernate/EnumUserType.java b/domain/src/main/java/org/acegisecurity/domain/hibernate/EnumUserType.java
index 8678d85f03..f616b90114 100644
--- a/domain/src/main/java/org/acegisecurity/domain/hibernate/EnumUserType.java
+++ b/domain/src/main/java/org/acegisecurity/domain/hibernate/EnumUserType.java
@@ -22,6 +22,7 @@ import java.sql.SQLException;
import java.sql.Types;
+import org.acegisecurity.domain.util.GenericsUtils;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
@@ -32,9 +33,11 @@ import org.hibernate.usertype.UserType;
* @version $Id$
*/
public class EnumUserType> implements UserType {
- private Class clazz = null;
- protected EnumUserType(Class c) {
- this.clazz = c;
+ private Class clazz = null;
+
+ @SuppressWarnings("unchecked")
+ protected EnumUserType() {
+ this.clazz = GenericsUtils.getGeneric(getClass());
}
private static final int[] SQL_TYPES = {Types.VARCHAR};
diff --git a/domain/src/main/java/org/acegisecurity/domain/impl/AbstractPersistableEntity.java b/domain/src/main/java/org/acegisecurity/domain/impl/AbstractPersistableEntity.java
index 34afee30bc..3d194f74ec 100644
--- a/domain/src/main/java/org/acegisecurity/domain/impl/AbstractPersistableEntity.java
+++ b/domain/src/main/java/org/acegisecurity/domain/impl/AbstractPersistableEntity.java
@@ -64,13 +64,4 @@ public abstract class AbstractPersistableEntity extends BusinessObject
public int getVersion() {
return version;
}
-
- /**
- * Sets the version numbers.
- *
- * @param version the new version number to use
- */
- public void setVersion(int version) {
- this.version = version;
- }
}
diff --git a/domain/src/main/java/org/acegisecurity/domain/impl/BusinessObject.java b/domain/src/main/java/org/acegisecurity/domain/impl/BusinessObject.java
index d2545b16ce..b564ef4fe2 100644
--- a/domain/src/main/java/org/acegisecurity/domain/impl/BusinessObject.java
+++ b/domain/src/main/java/org/acegisecurity/domain/impl/BusinessObject.java
@@ -51,7 +51,11 @@ public abstract class BusinessObject implements Serializable, Cloneable {
* Swallow cloning.
*
*
- * This method delegates to BeanUtils.cloneBean().
+ * This method delegates to BeanUtils.cloneBean(). Please note that
+ * this class uses serialization to achieve a clone, so this may
+ * represent a performance issue in certain applications. In
+ * such circumstances you should override this method and provide
+ * alternative cloning logic.
*
*
* @return a clone of the current instance
diff --git a/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityInteger.java b/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityInteger.java
index 8fe08ad00a..df41ca62da 100644
--- a/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityInteger.java
+++ b/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityInteger.java
@@ -17,6 +17,7 @@ package org.acegisecurity.domain.impl;
import java.io.Serializable;
+
/**
* A persistable entity that uses a Integer
based identity.
*
@@ -26,49 +27,22 @@ import java.io.Serializable;
public abstract class PersistableEntityInteger extends AbstractPersistableEntity {
//~ Instance fields ========================================================
- protected Integer id;
+ private Integer id;
//~ Methods ================================================================
- /**
- * DO NOT USE DIRECTLY.
- *
- *
- * Typically only used by the persistence layer, but provided with public
- * visibility to not limit flexibility.
- *
- *
- * @param id the new instance identity
- */
- public void setId(Integer id) {
- this.id = id;
- }
-
/**
* Obtains the persistence identity of this instance.
- *
- * Marked as abstract to remind users to implement. They'll need to implement
- * so their annotations reflect the correct sequence name.
*/
- public abstract Integer getId();
-
+ public Integer getId() {
+ return this.id;
+ }
+
/**
- * DO NOT USE DIRECTLY.
- *
- *
- * Use {@link #getId()} instead, as it provides the correct return type.
- * This method is only provided for use by the persistence layer and to
- * satisfy the {@link org.acegisecurity.domain.PersistableEntity}
- * interface contract.
- *
- *
- *
- * Internally delegates to {@link #getId()}.
- *
- *
- * @return the instance's identity
+ * Required solely because Hibernate
*/
public Serializable getInternalId() {
- return this.getId();
+ return this.id;
}
+
}
diff --git a/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityLong.java b/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityLong.java
index 7be2ec5bad..780ecad3a2 100644
--- a/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityLong.java
+++ b/domain/src/main/java/org/acegisecurity/domain/impl/PersistableEntityLong.java
@@ -17,6 +17,7 @@ package org.acegisecurity.domain.impl;
import java.io.Serializable;
+
/**
* A persistable entity that uses a Long
based identity.
*
@@ -26,49 +27,23 @@ import java.io.Serializable;
public abstract class PersistableEntityLong extends AbstractPersistableEntity {
//~ Instance fields ========================================================
- protected Long id;
+ private Long id;
//~ Methods ================================================================
-
- /**
- * DO NOT USE DIRECTLY.
- *
- *
- * Typically only used by the persistence layer, but provided with public
- * visibility to not limit flexibility.
- *
- *
- * @param id the new instance identity
- */
- public void setId(Long id) {
- this.id = id;
- }
-
/**
* Obtains the persistence identity of this instance.
*/
public Long getId() {
return this.id;
}
-
+
/**
- * DO NOT USE DIRECTLY.
- *
- *
- * Use {@link #getId()} instead, as it provides the correct return type.
- * This method is only provided for use by the persistence layer and to
- * satisfy the {@link org.acegisecurity.domain.PersistableEntity}
- * interface contract.
- *
- *
- *
- * Internally delegates to {@link #getId()}.
- *
- *
- * @return the instance's identity
+ * Required solely because Hibernate
*/
public Serializable getInternalId() {
- return this.getId();
+ return this.id;
}
+
+
}
diff --git a/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManager.java b/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManager.java
index a35056ae45..734f3da4d5 100644
--- a/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManager.java
+++ b/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManager.java
@@ -17,6 +17,7 @@ package org.acegisecurity.domain.service;
import org.acegisecurity.domain.PersistableEntity;
import org.acegisecurity.domain.dao.PaginatedList;
+import org.springframework.dao.DataAccessException;
import java.io.Serializable;
@@ -28,18 +29,16 @@ import java.util.List;
* PersistableEntity}, using JDK 1.5 generics.
*
*
- * This interface provides a remoting protocol compliant approach to accessing
- * services layer logic for a given application. A generics-based services
- * layer interface decreases development time because the basic CRUD and finder
- * operations can be specified in a typesafe fashion that reuses superclass
- * code.
+ * A design decision was to rely on by-reference calling semantics typical of
+ * recommended same-JVM (colocated) deployment environments. If you are using
+ * remoting you may need to provide a remoting facade that returns the updated
+ * object to the client.
*
*
*
* It is not envisioned that this interface will provide all services layer
* functions. The significant value of a services layer is the value-add beyond
- * simply fronting the DAO or applying validation/binding logic that is better
- * situated in the domain object or its validator. The type of value-adds
+ * simply fronting the DAO. The type of value-adds
* expected to be provided by a services layer include incrementing business
* identifiers (eg an invoice number); generating messages for logging/audit
* purposes (thus such messages are at a business transaction level of granularity,
@@ -47,17 +46,9 @@ import java.util.List;
* the message becomes unclear); updating related domain objects via
* their respective services layer beans (eg an invoice services layer bean
* would call the general journal services layer bean to create the accrual
- * accounting entries); making changes to a domain object that requires
- * logic that is unsuitable to put into a validator because it extends
- * beyond a single domain object instance or requires access to other persistent
- * entities (eg computing taxation appliable to an invoice based on a break-down
- * of each item on the order, its delivery destination, and the customer);
- * producing messages (eg notify another system the invoice was created or
- * email the customer via SMTP); provide a layer to locate transaction and
- * security configuration; expose a reasonably protocol-independent interface
- * to the application that can be used by a variety of web services and
- * client types; ensure any returned objects are eagerly loaded to a well-defined
- * interface contract etc.
+ * accounting entries); producing messages (eg notify another system the invoice
+ * was created or email the customer via SMTP); provide a layer to locate transaction
+ * and security configuration etc.
*
*
*
@@ -85,7 +76,7 @@ public interface ImmutableManager {
* @return all persistence instances (an empty List
will be
* returned if no matches are found)
*/
- public List findAll();
+ public List findAll() throws DataAccessException;
/**
* Find a List
of PersistableEntity
s, searched by
@@ -96,7 +87,7 @@ public interface ImmutableManager {
* @return the values with those identifiers (an empty List
* will be returned if no matches are found)
*/
- public List findId(Collection ids);
+ public List findId(Collection ids) throws DataAccessException;
/**
* Load a persistent instance by its identifier, although some properties
@@ -108,19 +99,8 @@ public interface ImmutableManager {
*
* @return the request item, or null
if not found
*/
- public E readId(Serializable id);
+ public E readId(Serializable id) throws DataAccessException;
- /**
- * Loads a persistent instance by its identifier, along with any
- * lazy loaded properties associated with that instance.
- *
- * @param id the identifier of the persistent instance desired to be
- * retrieved
- *
- * @return the request item, or null
if not found
- */
- public E readPopulatedId(Serializable id);
-
/**
* Find persistent instances with properties matching those of the passed
* PersistableEntity
.
@@ -143,33 +123,7 @@ public interface ImmutableManager {
* PaginatedList
is returned if no results match)
*/
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
- * String
s, and any Collection
s 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);
+ int maxElements) throws DataAccessException;
/**
* Find persistent instances with properties matching those of the passed
@@ -188,29 +142,8 @@ public interface ImmutableManager {
* PaginatedList
is returned if no results match)
*/
public PaginatedList scrollWithSubclasses(E value, int firstElement,
- int maxElements);
+ int maxElements) throws DataAccessException;
- /**
- * 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/ImmutableManagerImpl.java b/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManagerImpl.java
index 4ad3521d20..90ec9000cf 100644
--- a/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManagerImpl.java
+++ b/domain/src/main/java/org/acegisecurity/domain/service/ImmutableManagerImpl.java
@@ -23,8 +23,6 @@ import org.acegisecurity.domain.PersistableEntity;
import org.acegisecurity.domain.dao.Dao;
import org.acegisecurity.domain.dao.PaginatedList;
import org.acegisecurity.domain.util.GenericsUtils;
-
-import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.util.Assert;
@@ -34,39 +32,25 @@ import org.springframework.util.Assert;
* @author Ben Alex
* @version $Id$
*/
-public class ImmutableManagerImpl extends ApplicationObjectSupport implements ImmutableManager, InitializingBean {
+public class ImmutableManagerImpl extends ApplicationObjectSupport implements ImmutableManager {
//~ Instance fields ========================================================
/** The class that this instance provides services for */
private Class supportsClass;
- private String beanName;
protected Dao dao;
//~ Methods ================================================================
- public ImmutableManagerImpl() {
+ public ImmutableManagerImpl(Dao dao) {
+ // work out what domain object we support
this.supportsClass = GenericsUtils.getGeneric(getClass());
- if (supportsClass == null) {
- if (logger.isWarnEnabled()) {
- logger.warn("Could not determine the generics type - you will need to set manually");
- }
- }
- }
-
- public void setSupportsClass(Class supportClass) {
- this.supportsClass = supportClass;
- }
-
- public Class getSupportsClass() {
- return supportsClass;
- }
-
- public Dao getDao() {
- return dao;
- }
-
- public void setDao(Dao dao) {
+ Assert.notNull(this.supportsClass, "Could not determine the generics type");
+ Assert.isTrue(PersistableEntity.class.isAssignableFrom(supportsClass), "supportClass is not an implementation of PersistableEntity");
+
+ // store the DAO and check it also supports our domain object type
+ Assert.notNull(dao, "Non-null DAO (that supports the same domain object class as this services layer) is required as a constructor argument");
+ Assert.isTrue(dao.supports(supportsClass), "Dao '" + dao + "' does not support '" + supportsClass + "'");
this.dao = dao;
}
@@ -76,22 +60,6 @@ public class ImmutableManagerImpl extends Applicati
protected String getDefaultSortOrder() {
return "id";
}
-
- /**
- * Provides hook for custom subclasses to provide initialization behaviour
- *
- * @throws Exception
- */
- protected void doInitManager() throws Exception {}
-
- public final void afterPropertiesSet() throws Exception {
- Assert.notNull(supportsClass, "supportClass is required");
- Assert.isTrue(PersistableEntity.class.isAssignableFrom(supportsClass),
- "supportClass is not an implementation of PersistableEntity");
- Assert.notNull(dao, "Dao is null");
- Assert.isTrue(dao.supports(supportsClass), "Dao '" + dao + "' does not support '" + supportsClass + "'");
- doInitManager();
- }
public List findAll() {
return dao.findAll();
@@ -108,11 +76,6 @@ public class ImmutableManagerImpl extends Applicati
return dao.readId(id);
}
- public E readPopulatedId(Serializable id) {
- Assert.notNull(id);
- return dao.readPopulatedId(id);
- }
-
public PaginatedList scroll(E value, int firstElement,
int maxElements) {
Assert.notNull(value);
@@ -121,13 +84,6 @@ public class ImmutableManagerImpl extends Applicati
return dao.scroll(value, firstElement, maxElements, getDefaultSortOrder());
}
- 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);
@@ -136,20 +92,8 @@ public class ImmutableManagerImpl extends Applicati
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);
-
return this.supportsClass.equals(clazz);
}
-
- public void setBeanName(String beanName) {
- this.beanName = beanName;
- }
}
diff --git a/domain/src/main/java/org/acegisecurity/domain/util/GenericsUtils.java b/domain/src/main/java/org/acegisecurity/domain/util/GenericsUtils.java
index 36749b49ef..0121df8e29 100644
--- a/domain/src/main/java/org/acegisecurity/domain/util/GenericsUtils.java
+++ b/domain/src/main/java/org/acegisecurity/domain/util/GenericsUtils.java
@@ -17,7 +17,7 @@ public class GenericsUtils {
* @param clazz The class to introspect
* @return the first generic declaration, or null
if cannot be determined
*/
- public static Class getGeneric(Class clazz) {
+ public static Class getGeneric(Class clazz) {
Type genType = clazz.getGenericSuperclass();
if (genType instanceof ParameterizedType) {