package jomm.dao.impl;
import jomm.dao.DaoException;
import jomm.dao.IDomainObjectDao;
import jomm.dao.utils.HibernateUtils;
import org.hibernate.*;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.proxy.HibernateProxy;
import pt.estgp.estgweb.domain.DomainObject;
import pt.estgp.estgweb.domain.DomainSerializableObject;
import java.io.Serializable;
import java.util.*;
import static org.
hibernate.
criterion.
Restrictions.
eq;
/**
* This class will not be overwritten once it has been created. This is the
* superclass of all DAOs.
*/
public abstract class AbstractDao
<CLAZZ
> implements IDomainObjectDao
<CLAZZ
>
{
/**
* Return the number of results that match the given criteria.
*
* @param criteria to count results
* @return number count
*/
protected static long count
(Criteria criteria
)
{
// apply the rowCount projection to the criteria
criteria.
setProjection(Projections.
rowCount());
// count the results
1.5.0/docs/api/java/lang/Integer.html">Integer rowCount =
(1.5.0/docs/api/java/lang/Integer.html">Integer) criteria.
uniqueResult();
// disable the projection
criteria.
setProjection(null);
criteria.
setResultTransformer(CriteriaSpecification.
DISTINCT_ROOT_ENTITY);
return rowCount.
longValue();
}
/**
* @param maxField field to find max to load object
* @return last inserted object
*/
public CLAZZ getLast
(1.5.0/docs/api/java/lang/String.html">String maxField
)
{
List
<CLAZZ
> objs = createCriteria
()
.
addOrder(Order.
desc(maxField
))
.
setMaxResults(1
)
.
list();
if (objs
!=
null && objs.
size() > 0
)
return objs.
get(0
);
else
return null;
}
public CLAZZ findMaxId
(1.5.0/docs/api/java/lang/String.html">String field
)
{
Criteria c = createCriteria
(getReferenceClass
());
c.
setProjection(Projections.
projectionList().
add(Projections.
max(field
)));
c.
setMaxResults(1
);
List
<CLAZZ
> l = c.
list();
if (l ==
null)
return null;
else
return l.
get(0
);
}
/**
* Return the specific Object class that will be used for class-specific
* implementation of this DAO.
*
* @return the reference Class
*/
protected abstract 1.5.0/docs/api/java/lang/Class.html">Class getReferenceClass
();
/**
* Close used resources.
*/
public static void close
()
{
flush
();
commit
();
getCurrentSession
().
close();
}
/**
* Flush used resources.
*/
public static void flush
()
{
try
{
getCurrentSession
().
flush();
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
public static void commit
()
{
try
{
getCurrentSession
().
getTransaction().
commit();
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* ***************
* <p/>
* <p/>
* Returns the Session object associated with either the current JTA transaction or the current thread.
*
* @return active examples
* @throws IllegalStateException when examples throws errors
*/
public static Session getCurrentSession
() throws 1.5.0/docs/api/java/lang/IllegalStateException.html">IllegalStateException
{
return HibernateUtils.
getCurrentSession();
}
/**
* Ensure that the given object is initialized from the database.
*
* @param obj to inicialize in examples
*/
public static void initialize
(5+0%2Fdocs%2Fapi+Object">Object obj
)
{
try
{
Hibernate.
initialize(obj
);
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Create a criteria for this DAO using the correct LockMode.
*
* @return Criteria
*/
protected final Criteria createCriteria
()
{
return createCriteria
(getReferenceClass
());
}
/**
* Create a criteria for this DAO and the given persistent class, using the
* correct LockMode.
*
* @param clazz Class to criteria
* @return Criteria
*/
protected final Criteria createCriteria
(1.5.0/docs/api/java/lang/Class.html">Class clazz
)
{
return getCurrentSession
().
createCriteria(clazz
);
}
/**
* Create a Query for this DAO and the given persistent class, using the
* correct LockMode.
*
* @param queryString Str in HQL
* @return Query from queryString
*/
protected final 1.5.0/docs/api/javax/management/Query.html">Query createQuery
(1.5.0/docs/api/java/lang/String.html">String queryString
)
{
try
{
return getCurrentSession
().
createQuery(queryString
);
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Create an SQLQuery based on the given query string.
*
* @param queryString an SQL query
* @return an SQLQuery
*/
final SQLQuery createSqlQuery
(1.5.0/docs/api/java/lang/String.html">String queryString
)
{
try
{
return getCurrentSession
().
createSQLQuery(queryString
);
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Count all objects of this DAO's reference class.
*/
public final long countAll
()
{
try
{
// criteria selecting all instances of the referred class
return count
(createCriteria
());
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
public List
<CLAZZ
> getAll
()
{
Session s = getCurrentSession
();
// Duarte Santos
1.5.0/docs/api/javax/management/Query.html">Query q = s.
createQuery("from " + getReferenceClass
().
getName());
return q.
list();
}
/**
* Return all objects related to the implementation of this DAO with no
* filters.
*
* @SuppressWarnings("unchecked")
*/
public List
<CLAZZ
> findAll
()
{
try
{
return createCriteria
().
list();
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Returns results as a page.
* <p/>
* Finds "sizeOfPage" objects, starting from the page "pageIndex".
*
* @param pageIndex page number
* @param sizeOfPage results in page
* @return persistent objects
* <BR><B>author <a href="mailto:luismmribeiro@gmail.com">Luis Ribeiro</a></B>
* @SuppressWarnings("unchecked")
*/
public List
<CLAZZ
> findByPage
(int pageIndex,
int sizeOfPage
)
{
try
{
Criteria criteria = createCriteria
();
criteria.
setFirstResult(pageIndex
* sizeOfPage
);
criteria.
setMaxResults(sizeOfPage
);
return criteria.
list();
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Obtain an instance of Query for a named query string defined in the
* mapping file.
*
* @param name the name of a query defined externally
* @return Query
*/
protected final 1.5.0/docs/api/javax/management/Query.html">Query getNamedQuery
(1.5.0/docs/api/java/lang/String.html">String name
)
{
try
{
return getCurrentSession
().
getNamedQuery(name
);
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Used by the base DAO classes but here for your modification Load object
* matching the given key and return it.
*
* @SuppressWarnings("unchecked")
*/
public static 5+0%2Fdocs%2Fapi+Object">Object load
(1.5.0/docs/api/java/lang/Class.html">Class cl,
1.5.0/docs/api/java/io/Serializable.html">Serializable dbKey
)
{
try
{
5+0%2Fdocs%2Fapi+Object">Object c = getCurrentSession
().
load(cl, dbKey
);
if (c
!=
null && !((DomainObject
) c
).
getReferenceClass().
getName().
equals(cl.
getName()))
{
1.5.0/docs/api/java/lang/Class.html">Class cC =
((DomainObject
) c
).
getReferenceClass();
return getCurrentSession
().
load(cC, dbKey
);
}
return c
;
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
*
* @param o
* @return
*/
public CLAZZ narrow
(CLAZZ o
)
{
if(o ==
null)
return null;
if (o
instanceof HibernateProxy
)
{
return (CLAZZ
) ((HibernateProxy
)o
).
getHibernateLazyInitializer().
getImplementation();
}
return o
;
}
/**
* Used by the base DAO classes but here for your modification Load object
* matching the given key and return it.
*
* @SuppressWarnings("unchecked")
*/
public static 5+0%2Fdocs%2Fapi+Object">Object get
(1.5.0/docs/api/java/lang/Class.html">Class cl,
1.5.0/docs/api/java/io/Serializable.html">Serializable dbKey
)
{
try
{
5+0%2Fdocs%2Fapi+Object">Object c = getCurrentSession
().
get(cl, dbKey
);
if (c
!=
null && !((DomainObject
) c
).
getReferenceClass().
getName().
equals(cl.
getName()))
{
1.5.0/docs/api/java/lang/Class.html">Class cC =
((DomainObject
) c
).
getReferenceClass();
return getCurrentSession
().
get(cC, dbKey
);
}
return c
;
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Used by the base DAO classes but here for your modification Load object
* matching the given key and return it.
*
* @SuppressWarnings("unchecked")
*/
public static 5+0%2Fdocs%2Fapi+Object">Object load
(1.5.0/docs/api/java/lang/String.html">String cl,
1.5.0/docs/api/java/io/Serializable.html">Serializable dbKey
)
{
try
{
5+0%2Fdocs%2Fapi+Object">Object c = getCurrentSession
().
load(cl, dbKey
);
if (c
!=
null && !((DomainObject
) c
).
getReferenceClass().
getName().
equals(cl
))
{
1.5.0/docs/api/java/lang/Class.html">Class cC =
((DomainObject
) c
).
getReferenceClass();
return getCurrentSession
().
load(cC, dbKey
);
}
return c
;
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Used by the base DAO classes but here for your modification Load object
* matching the given key and return it.
*
* @SuppressWarnings("unchecked")
*/
public static 5+0%2Fdocs%2Fapi+Object">Object get
(1.5.0/docs/api/java/lang/String.html">String cl,
1.5.0/docs/api/java/io/Serializable.html">Serializable dbKey
)
{
try
{
5+0%2Fdocs%2Fapi+Object">Object c = getCurrentSession
().
get(cl, dbKey
);
if (c
!=
null && !((DomainObject
) c
).
getReferenceClass().
getName().
equals(cl
))
{
1.5.0/docs/api/java/lang/Class.html">Class cC =
((DomainObject
) c
).
getReferenceClass();
return getCurrentSession
().
get(cC, dbKey
);
}
return c
;
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Used by the base DAO classes but here for your modification Load object
* matching the given key and return it.
*
* @SuppressWarnings("unchecked")
*/
public final CLAZZ load
(1.5.0/docs/api/java/io/Serializable.html">Serializable dbKey
)
{
try
{
CLAZZ c =
(CLAZZ
) getCurrentSession
().
load(getReferenceClass
(), dbKey
);
if (c
!=
null && !((DomainObject
) c
).
getReferenceClass().
getName().
equals(getReferenceClass
().
getName()))
{
1.5.0/docs/api/java/lang/Class.html">Class cC =
((DomainObject
) c
).
getReferenceClass();
return (CLAZZ
) getCurrentSession
().
load(cC, dbKey
);
}
return c
;
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Used by the base DAO classes but here for your modification Load object
* matching the given key and return it.
*
* @SuppressWarnings("unchecked")
*/
public final CLAZZ getOrNull
(1.5.0/docs/api/java/io/Serializable.html">Serializable dbKey
)
{
try
{
return (CLAZZ
) getCurrentSession
().
get(getReferenceClass
(), dbKey
);
}
catch (ObjectNotFoundException e
)
{
return null;
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Used by the base DAO classes but here for your modification Load object
* matching the given key and return it.
*
* @SuppressWarnings("unchecked")
*/
public final CLAZZ loadOrNull
(1.5.0/docs/api/java/io/Serializable.html">Serializable dbKey
)
{
try
{
CLAZZ obj =
(CLAZZ
) getCurrentSession
().
load(getReferenceClass
(), dbKey
);
obj.
toString();
return obj
;
}
catch (ObjectNotFoundException e
)
{
return null;
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
public CLAZZ loadOrNullLockUpgrade
(1.5.0/docs/api/java/io/Serializable.html">Serializable dbKey
)
{
return loadOrNullLockWrite
("id", dbKey
);
}
/**
* Used by the base DAO classes but here for your modification Load object
* matching the given key and return it.
*
* @SuppressWarnings("unchecked")
*/
public CLAZZ loadOrNullLockWrite
(1.5.0/docs/api/java/lang/String.html">String field,
1.5.0/docs/api/java/io/Serializable.html">Serializable dbKey
)
{
try
{
return (CLAZZ
) createCriteria
().
add(eq
(field, dbKey
)).
uniqueResult();
}
catch (ObjectNotFoundException e
)
{
return null;
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Remove this instance from the system cache.
* <p/>
* <P>Changes to the instance will not be synchronized with the database.
*
* @param object a persistent instance
*/
public void evict
(CLAZZ object
)
{
try
{
getCurrentSession
().
evict(object
);
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Wrap Hibernate's Session.get(Class, Serializable).
*
* @SuppressWarnings("unchecked")
*/
public final CLAZZ get
(1.5.0/docs/api/java/io/Serializable.html">Serializable dbKey
)
{
try
{
CLAZZ c =
(CLAZZ
) getCurrentSession
().
get(getReferenceClass
(), dbKey
);
if (c
!=
null && !((DomainObject
) c
).
getReferenceClass().
getName().
equals(getReferenceClass
().
getName()))
{
1.5.0/docs/api/java/lang/Class.html">Class cC =
((DomainObject
) c
).
getReferenceClass();
return (CLAZZ
) getCurrentSession
().
get(cC, dbKey
);
}
return c
;
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Used by the base DAO classes but here for your modification Persist the
* given transient instance, first assigning a generated identifier. (Or
* using the current value of the identifier property if the assigned
* generator is used.)
*/
public 1.5.0/docs/api/java/io/Serializable.html">Serializable save
(CLAZZ obj
)
{
try
{
DomainObject o =
(DomainObject
) obj
;
o.
setSaveDate(new 5+0%2Fdocs%2Fapi+Date">Date());
return (1.5.0/docs/api/java/io/Serializable.html">Serializable) getCurrentSession
().
save(obj
);
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Used by the base DAO classes but here for your modification Persist the
* given transient instance, first assigning a generated identifier. (Or
* using the current value of the identifier property if the assigned
* generator is used.)
*/
public final void saveOrUpdate
(CLAZZ obj
)
{
try
{
getCurrentSession
().
saveOrUpdate(obj
);
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Saves a collection of objects without returning the DbKey.
* <p/>
* To obtain the DbKey, use the object itself.
*
* @param objs List of objects to save
*/
public final void save
(Collection
<CLAZZ
> objs
)
{
try
{
Session session = getCurrentSession
();
for (CLAZZ obj : objs
)
{
session.
save(obj
);
}
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Used by the base DAO classes but here for your modification Either save()
* or update() the given instance, depending upon the value of its
* identifier property.
*
* @param obj object to save or update
* @throws DaoException when Hibernate trwoes Hibernate Exception
*/
protected final void saveOrReattach
(CLAZZ obj
) throws DaoException
{
try
{
getCurrentSession
().
saveOrUpdate(obj
);
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Used by the base DAO classes but here for your modification Update the
* persistent state associated with the given identifier. An exception is
* thrown if there is a persistent instance with the same identifier in the
* current examples.
*
* @param obj a transient instance containing updated state
* @throws DaoException when Hibernate trwoes Hibernate Exception
*/
public final void reattach
(CLAZZ obj
) throws DaoException
{
try
{
getCurrentSession
().
update(obj
);
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Remove this instance from the examples cache. Changes to the instance will
* not be synchronized with the database. This operation cascades to
* associated instances if the association is mapped with cascade="all" or
* cascade="all-delete-orphan".
*
* @param object a persistent instance
* @throws DaoException when Hibernate trwoes Hibernate Exception
*/
protected final void dettach
(CLAZZ object
) throws DaoException
{
try
{
getCurrentSession
().
evict(object
);
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Used by the base DAO classes but here for your modification Remove a
* persistent instance from the datastore. The argument may be an instance
* associated with the receiving Session or a transient instance with an
* identifier associated with existing persistent state.
*/
public final void delete
(CLAZZ obj
)
{
try
{
getCurrentSession
().
delete(obj
);
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Refresh a collection of objects.
*
* @param objs Objects to refreh
*/
public final void refresh
(Collection
<CLAZZ
> objs
)
{
try
{
Session session = getCurrentSession
();
for (CLAZZ obj : objs
)
{
session.
refresh(obj
);
}
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Refresh a collection of objects.
*
* @param obj Object to refreh
*/
public final void refresh
(CLAZZ obj
)
{
try
{
Session session = getCurrentSession
();
session.
refresh(obj
);
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Refresh a collection of objects.
*
* @param objs Objects to delete
*/
public final void evictAndDelete
(Collection
<CLAZZ
> objs
)
{
try
{
for (CLAZZ obj : objs
)
{
1.5.0/docs/api/java/lang/System.html">System.
out.
println("CLEARING: " + obj
);
evictAndDelete
(obj
);
}
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Refresh a collection of objects.
*
* @param obj Object to delete
*/
public final void evictAndDelete
(CLAZZ obj
)
{
try
{
Session session = getCurrentSession
();
obj =
(CLAZZ
) session.
load(getReferenceClass
(),
((DomainSerializableObject
) obj
).
getSerializable());
session.
delete(obj
);
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Deletes a collection of objects.
*
* @param objs Objects to delete
*/
public final void reattach
(Collection
<CLAZZ
> objs
)
{
try
{
Session session = getCurrentSession
();
for (CLAZZ obj : objs
)
{
session.
update(obj
);
}
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Deletes a collection of objects.
*
* @param objs Objects to delete
*/
public final void delete
(Collection
<CLAZZ
> objs
)
{
try
{
Session session = getCurrentSession
();
for (CLAZZ obj : objs
)
{
session.
delete(obj
);
}
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Completely clearObjects the examples. Evict all loaded instances and cancel all pending
* saves, updates and deletions. Do not close open iterators or instances of
* <tt>ScrollableResults</tt>.
*/
public static void clear
()
{
getCurrentSession
().
clear();
}
/**
* Delete an object by its key.
*
* @param dbKey the database key
* @return true or false depending on the operation success
*/
public boolean delete
(1.5.0/docs/api/java/io/Serializable.html">Serializable dbKey
)
{
try
{
final CLAZZ object = load
(dbKey
);
getCurrentSession
().
delete(object
);
return true;
}
catch (HibernateException e
)
{
throw new DaoException
(e
);
}
}
/**
* Apply the dbKeys filters for the objects being filtered by the given criteria.
*
*/
// protected static void applyDbKeysFilter(Criteria criteria, List objectDbKeys) {
//
// // if there are no matches then we need a constraint
// // that will always evaluate to false
// if (objectDbKeys.isEmpty()) {
// criteria.add(Restrictions.isNull(PROPERTY_id));
// }
// else {
// Disjunction disjunction = Restrictions.disjunction();
//
// for (Iterator it = objectDbKeys.iterator(); it.hasNext(); ) {
// disjunction.add(Restrictions.eq(PROPERTY_id, it.next()));
// }
//
// criteria.add(disjunction);
// }
// }
/**
* Return the given criteria with additional paging constraints applied to it.
*
* @param criteria criteria to turn paged
* @param pageSize page size in results
* @param pageNumber actual page
* @param count number of pages
* @return Criteria paged
*/
protected static Criteria createPagedCriteria
(Criteria criteria,
int pageSize,
int pageNumber,
long count
)
{
if (pageSize
>= 0
&& pageSize
< count
)
{
return criteria.
setFirstResult(pageSize
* pageNumber
)
.
setMaxResults(pageSize
);
}
return criteria
;
}
/**
* return deleted objects
* @param incompleteList
* @param persistentList
* @param comparator
* @return
*/
public List
<CLAZZ
> deleteMissing
(Collection
<CLAZZ
> incompleteList, Collection
<CLAZZ
> persistentList,Comparator
<CLAZZ
> comparator
)
{
List
<CLAZZ
> deletedObjects =
new ArrayList
<CLAZZ
>();
//Remover apagados
Iterator
<CLAZZ
> iterPersistentObjects = persistentList.
iterator();
while(iterPersistentObjects.
hasNext())
{
CLAZZ persisitentObj = iterPersistentObjects.
next();
boolean found =
false;
for(CLAZZ incompleteListObj: incompleteList
)
{
if(comparator.
compare(incompleteListObj,persisitentObj
)==0
)
{
found =
true;
break;
}
}
if(!found
)
{
iterPersistentObjects.
remove();
deletedObjects.
add(persisitentObj
);
delete
(persisitentObj
);
}
}
return deletedObjects
;
}
}