From f211a354e645bf189559afb4eefdf5625ed35fd3 Mon Sep 17 00:00:00 2001 From: rkv Date: Fri, 14 Dec 2012 05:36:59 +0000 Subject: [PATCH] DAO's method getFilteredList is improved so that it is possible to do subqueries by properties of child objects. Unit tests are improved. --- .../dao/kernel/AbstractGenericDAOImpl.java | 68 ++++-- .../org/splat/dal/dao/kernel/GenericDAO.java | 38 +++- .../splat/dao/TestKnowledgeElementDAO.java | 204 +++++++++++++----- 3 files changed, 242 insertions(+), 68 deletions(-) diff --git a/Workspace/Siman-Common/src/org/splat/dal/dao/kernel/AbstractGenericDAOImpl.java b/Workspace/Siman-Common/src/org/splat/dal/dao/kernel/AbstractGenericDAOImpl.java index c30ed28..0aef576 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/dao/kernel/AbstractGenericDAOImpl.java +++ b/Workspace/Siman-Common/src/org/splat/dal/dao/kernel/AbstractGenericDAOImpl.java @@ -29,12 +29,13 @@ import org.springframework.orm.hibernate3.support.HibernateDaoSupport; * @param * Primary key class */ -public abstract class AbstractGenericDAOImpl extends - HibernateDaoSupport implements GenericDAO { +public abstract class AbstractGenericDAOImpl + extends HibernateDaoSupport implements GenericDAO { /** * Unchecked warning specification. */ private static final String UNCHECKED = "unchecked"; + /** * Persist the newInstance object into database. * @@ -92,8 +93,9 @@ public abstract class AbstractGenericDAOImpl extends */ public T findByCriteria(final Properties andParams) { Criterion aCondition = null; - for (String aName: andParams.stringPropertyNames()) { - aCondition = Restrictions.and(aCondition, Restrictions.eq(aName, andParams.get(aName))); + for (String aName : andParams.stringPropertyNames()) { + aCondition = Restrictions.and(aCondition, Restrictions.eq(aName, + andParams.get(aName))); } return findByCriteria(aCondition); } @@ -116,10 +118,10 @@ public abstract class AbstractGenericDAOImpl extends * @return an ordered list of all objects of the considered type T */ @SuppressWarnings(UNCHECKED) - public List getAll(final Order ... anOrder) { + public List getAll(final Order... anOrder) { Criteria aCriteria = getSession().createCriteria(getType()); for (Order order : anOrder) { - if (anOrder != null) { + if (order != null) { aCriteria.addOrder(order); } } @@ -148,17 +150,57 @@ public abstract class AbstractGenericDAOImpl extends * @return a list of objects filtered according to the given criteria */ @SuppressWarnings(UNCHECKED) - public List getFilteredList(final Criterion aCondition, final Order ... anOrder) { + public List getFilteredList(final Criterion aCondition, + final Order... anOrder) { Criteria aCriteria = getSession().createCriteria(getType()).add( aCondition); for (Order order : anOrder) { - if (anOrder != null) { + if (order != null) { aCriteria.addOrder(order); } } return aCriteria.list(); } + /** + * Retrieve a list of objects which were previously persisted to the database using the given criteria. + * + * @param joinField + * a field containing object to apply the condition + * + * @param aCondition + * a search condition + * @return a list of objects filtered according to the given criteria + */ + public List getFilteredList(final String joinField, + final Criterion aCondition) { + return getFilteredList(joinField, aCondition, (Order) null); + } + + /** + * Retrieve a list of objects which were previously persisted to the database using the given criteria. + * + * @param joinField + * a field containing object to apply the condition + * + * @param aCondition + * a search condition + * @param anOrder + * a result list order. Null is ignored and in such case the result list is unordered. + * @return a list of objects filtered according to the given criteria + */ + @SuppressWarnings(UNCHECKED) + public List getFilteredList(final String joinField, + final Criterion aCondition, final Order... anOrder) { + Criteria aCriteria = getSession().createCriteria(getType()); + for (Order order : anOrder) { + if (order != null) { + aCriteria.addOrder(order); + } + } + return aCriteria.createCriteria(joinField).add(aCondition).list(); + } + /** * Retrieve a list of objects which were previously persisted to the database using the given criteria. * @@ -167,7 +209,7 @@ public abstract class AbstractGenericDAOImpl extends * @return a list of objects filtered according to the given criteria */ public List getFilteredList(final Properties andParams) { - return getFilteredList(andParams); + return getFilteredList(andParams, (Order) null); } /** @@ -179,10 +221,12 @@ public abstract class AbstractGenericDAOImpl extends * a result list order. Null is ignored and in such case the result list is unordered. * @return a list of objects filtered according to the given criteria */ - public List getFilteredList(final Properties andParams, final Order ... anOrder) { + public List getFilteredList(final Properties andParams, + final Order... anOrder) { Criterion aCondition = null; - for (String aName: andParams.stringPropertyNames()) { - aCondition = Restrictions.and(aCondition, Restrictions.eq(aName, andParams.get(aName))); + for (String aName : andParams.stringPropertyNames()) { + aCondition = Restrictions.and(aCondition, Restrictions.eq(aName, + andParams.get(aName))); } return getFilteredList(aCondition, anOrder); } diff --git a/Workspace/Siman-Common/src/org/splat/dal/dao/kernel/GenericDAO.java b/Workspace/Siman-Common/src/org/splat/dal/dao/kernel/GenericDAO.java index fef4140..fa8ee40 100644 --- a/Workspace/Siman-Common/src/org/splat/dal/dao/kernel/GenericDAO.java +++ b/Workspace/Siman-Common/src/org/splat/dal/dao/kernel/GenericDAO.java @@ -44,7 +44,7 @@ public interface GenericDAO { * new object as a transient instance */ public void saveOrUpdate(final T newInstance); - + /** * Retrieve an object that was previously persisted to the database using the indicated id as primary key. * @@ -124,6 +124,42 @@ public interface GenericDAO { */ public List getFilteredList(Criterion aCondition, Order... anOrder); + /** + * Retrieve a list of objects which were previously persisted to the database using the given criteria.
+ * Joined field allows applying a filter condition to the child object.
+ * In the following example we get all knowledge elements of the "bestpractice" knowledge type:
+ * knowledgeElementDAO.getFilteredList( + "type", Restrictions.eq("name", "bestpractice")); + * + * @param joinField + * a field containing object to apply the condition + * + * @param aCondition + * a search condition + * @return a list of objects filtered according to the given criteria + */ + public List getFilteredList(final String joinField, + final Criterion aCondition); + + /** + * Retrieve a list of objects which were previously persisted to the database using the given criteria.
+ * Joined field allows applying a filter condition to the child object.
+ * In the following example we get all knowledge elements of the "bestpractice" knowledge type:
+ * knowledgeElementDAO.getFilteredList( + "type", Restrictions.eq("name", "bestpractice"), Order.asc("title")); + * + * @param joinField + * a field containing object to apply the condition + * + * @param aCondition + * a search condition + * @param anOrder + * a result list order. Null is ignored and in such case the result list is unordered. + * @return a list of objects filtered according to the given criteria + */ + public List getFilteredList(final String joinField, + final Criterion aCondition, final Order... anOrder); + /** * Retrieve a list of objects which were previously persisted to the database using the given criteria. * diff --git a/Workspace/Siman-Common/src/test/splat/dao/TestKnowledgeElementDAO.java b/Workspace/Siman-Common/src/test/splat/dao/TestKnowledgeElementDAO.java index 42df6a2..47bc675 100644 --- a/Workspace/Siman-Common/src/test/splat/dao/TestKnowledgeElementDAO.java +++ b/Workspace/Siman-Common/src/test/splat/dao/TestKnowledgeElementDAO.java @@ -9,7 +9,10 @@ package test.splat.dao; import java.util.Date; +import java.util.List; +import org.hibernate.criterion.Order; +import org.hibernate.criterion.Restrictions; import org.splat.dal.bo.kernel.User; import org.splat.dal.bo.som.KnowledgeElement; import org.splat.dal.bo.som.KnowledgeElementType; @@ -66,7 +69,7 @@ public class TestKnowledgeElementDAO extends BaseTest { *
    *
  • Object is created in the database successfully
    *
  • - *
  • Exception is thrown
    + *
  • Another new object is created with new generated id
    *
  • *
* @@ -84,21 +87,25 @@ public class TestKnowledgeElementDAO extends BaseTest { MissedPropertyException, MultiplyDefinedException { LOG.debug(">>>>> BEGIN testCreate()"); startNestedTransaction(); - + KnowledgeElement aKelm = getKnowledgeElement(); // Call DAO's create method for a good transient knowledge element. - Long id = _knowledgeElementDAO.create(aKelm); + long id = _knowledgeElementDAO.create(aKelm); Assert.assertNotNull(id, "Create method returns null instead of a new id."); Assert.assertTrue(id > 0, "The new id is not a positive number."); + + LOG.debug("Created id: " + id); + KnowledgeElement aKelmFound = getHibernateTemplate().get( KnowledgeElement.class, id); compareObjects(aKelmFound, aKelm); + _knowledgeElementDAO.flush(); // Call DAO's create method for a knowledge element with non-zero id. KnowledgeElement aBadKelm = new KnowledgeElement( (new KnowledgeElement.Properties()) - .setTitle("Test knowledge element") + .setTitle("2.Bad test knowledge element") .setAuthor(aKelm.getAuthor()) .setOwnerScenario(aKelm.getOwnerScenario()) .setType(aKelm.getType()) @@ -106,15 +113,45 @@ public class TestKnowledgeElementDAO extends BaseTest { .setValue( "This is another test knowledge element.\nIt is created by the unit test.")); aBadKelm.setIndex(aKelmFound.getIndex()); - try { - _knowledgeElementDAO.create(aBadKelm); - getHibernateTemplate().flush(); - Assert.fail("Creation with existing id must be failed."); - } catch (Exception e) { - LOG.debug("Expected exception is thrown: " - + e.getClass().getSimpleName() + ": " + e.getMessage()); - } - + + _knowledgeElementDAO.flush(); + List res = _knowledgeElementDAO.getAll(Order + .asc("rid")); + + Assert.assertNotNull(res, + "Method getFilteredList must not return null."); + Assert.assertEquals(res.size(), 1, "Number of found objects is wrong."); + Assert.assertEquals(aBadKelm.getIndex(), id, "Id must be equal."); + + Assert.assertNotNull(aBadKelm.getIndex(), + "Create method returns null instead of a new id."); + Assert.assertTrue(aBadKelm.getIndex() > 0, + "The new id is not a positive number."); + + long id2 = _knowledgeElementDAO.create(aBadKelm); + + _knowledgeElementDAO.flush(); + + LOG.debug("Created second id: " + id2); + + res = _knowledgeElementDAO.getAll(); + _knowledgeElementDAO.flush(); + + Assert.assertNotNull(res, + "Method getFilteredList must not return null."); + Assert.assertNotNull(res.get(0), + "Method getFilteredList must not return null."); + Assert.assertNotNull(res.get(1), + "Method getFilteredList must not return null."); + Assert.assertEquals(res.size(), 2, "Number of found objects is wrong."); + Assert.assertEquals(res.get(0).getIndex(), id, + "Sorting is incorrect or id of the first element is wrong."); + Assert.assertEquals(res.get(1).getIndex(), id2, + "Sorting is incorrect or id of the second element is wrong."); + id = res.get(0).getIndex(); + id2 = res.get(1).getIndex(); + Assert.assertFalse(id == id2, "Ids of objects must not be duplicated."); + rollbackNestedTransaction(); LOG.debug(">>>>> END testCreate()"); } @@ -135,7 +172,7 @@ public class TestKnowledgeElementDAO extends BaseTest { *
    *
  • Object is found in the database successfully
    *
  • - *
  • Exception is thrown
    + *
  • Result of search is null
    *
  • *
* @@ -153,7 +190,7 @@ public class TestKnowledgeElementDAO extends BaseTest { MissedPropertyException, MultiplyDefinedException { LOG.debug(">>>>> BEGIN testGet()"); startNestedTransaction(); - + KnowledgeElement aKelm = getKnowledgeElement(); // Call DAO's create method for a good transient knowledge element. Long id = _knowledgeElementDAO.create(aKelm); @@ -167,34 +204,21 @@ public class TestKnowledgeElementDAO extends BaseTest { compareObjects(aKelmFound, aKelm); // Call DAO's get method for a not existing id. - try { - aKelmFound = _knowledgeElementDAO.get(-1L); - getHibernateTemplate().flush(); - Assert - .fail("Getting an object with not existing id must be failed."); - } catch (Exception e) { - LOG.debug("Expected exception is thrown: " - + e.getClass().getSimpleName() + ": " + e.getMessage()); - } - try { - aKelmFound = _knowledgeElementDAO.get(0L); - getHibernateTemplate().flush(); - Assert - .fail("Getting an object with not existing id must be failed."); - } catch (Exception e) { - LOG.debug("Expected exception is thrown: " - + e.getClass().getSimpleName() + ": " + e.getMessage()); - } - try { - aKelmFound = _knowledgeElementDAO.get(id + 1); - getHibernateTemplate().flush(); - Assert - .fail("Getting an object with not existing id must be failed."); - } catch (Exception e) { - LOG.debug("Expected exception is thrown: " - + e.getClass().getSimpleName() + ": " + e.getMessage()); - } - + aKelmFound = _knowledgeElementDAO.get(-1L); + getHibernateTemplate().flush(); + Assert.assertNull(aKelmFound, + "A found object with not existing id must be null."); + + aKelmFound = _knowledgeElementDAO.get(0L); + getHibernateTemplate().flush(); + Assert.assertNull(aKelmFound, + "A found object with not existing id must be null."); + + aKelmFound = _knowledgeElementDAO.get(id + 1); + getHibernateTemplate().flush(); + Assert.assertNull(aKelmFound, + "A found object with not existing id must be null."); + rollbackNestedTransaction(); LOG.debug(">>>>> END testGet()"); } @@ -299,7 +323,7 @@ public class TestKnowledgeElementDAO extends BaseTest { LOG.debug("Expected exception is thrown: " + e.getClass().getSimpleName() + ": " + e.getMessage()); } - + rollbackNestedTransaction(); LOG.debug(">>>>> END testUpdate()"); } @@ -354,15 +378,8 @@ public class TestKnowledgeElementDAO extends BaseTest { Assert.assertNull(aKelmFound, "Deleted object must not be found."); // Call DAO's delete method for a not existing id. - try { - _knowledgeElementDAO.delete(aKelm); - getHibernateTemplate().flush(); - Assert.fail("Delete with with not existing id must be failed."); - } catch (Exception e) { - LOG.debug("Expected exception is thrown: " - + e.getClass().getSimpleName() + ": " + e.getMessage()); - } - + getHibernateTemplate().flush(); + rollbackNestedTransaction(); LOG.debug(">>>>> END testDelete()"); } @@ -395,7 +412,7 @@ public class TestKnowledgeElementDAO extends BaseTest { "noreply@salome-platform.org"); uprop.disableCheck(); User anAuthor = new User(uprop); - ht.update(anAuthor); + ht.saveOrUpdate(anAuthor); // Create a test study Study.Properties stprops = new Study.Properties().setReference( "TST_SID_01").setTitle("TST_Study").setManager(anAuthor); @@ -415,7 +432,7 @@ public class TestKnowledgeElementDAO extends BaseTest { // Prepare a knowledge element transient object kprops - .setTitle("Test knowledge element") + .setTitle("1. Test knowledge element") .setAuthor(anAuthor) .setOwnerScenario(aScenario) .setType(aKType) @@ -457,4 +474,81 @@ public class TestKnowledgeElementDAO extends BaseTest { Assert.assertEquals(anActual.getIndex(), anExpected.getIndex(), "Knowledge Element index is not saved."); } + + /** + * Test of getting a filtered list of knowledge elements.
+ * Description :
+ * Create two knowledge elements and try to get them from the database.
+ * Action :
+ * 1. Find objects with the given value of the property of a child object.
+ * 2. Get ordered list of objects with the given value of the property of a child object.
+ * Test data :
+ * no input parameters
+ * no input parameters
+ * + * Outcome results:
+ * + *
    + *
  • Objects are found in the database successfully
    + *
  • + *
  • Objects are found in the database and sorted in the right order
    + *
  • + *
+ *
+ * + * @throws InvalidPropertyException + * if an invalid property is used when creating objects + * @throws MultiplyDefinedException + * when trying to create an object with already existing id + * @throws MissedPropertyException + * if a mandatory property is not defined for an object to be created + * + */ + @Test + public void testGetFilteredList() throws InvalidPropertyException, + MissedPropertyException, MultiplyDefinedException { + LOG.debug(">>>>> BEGIN testGetFilteredList()"); + startNestedTransaction(); + + // Create several objects in the database + KnowledgeElement aKelm = getKnowledgeElement(); + long id = _knowledgeElementDAO.create(aKelm); + KnowledgeElement aNewKelm = new KnowledgeElement( + (new KnowledgeElement.Properties()) + .setTitle("Test knowledge element N2") + .setAuthor(aKelm.getAuthor()) + .setOwnerScenario(aKelm.getOwnerScenario()) + .setType(aKelm.getType()) + .setDate(aKelm.getDate()) + .setValue( + "This is another test knowledge element.\nIt is created by the unit test.")); + long id2 = _knowledgeElementDAO.create(aNewKelm); + + _knowledgeElementDAO.flush(); + + // //////////////////////////////////////////////////// + // Call DAO's getFilteredList method without order parameter. + List res = _knowledgeElementDAO.getFilteredList( + "type", Restrictions.eq("name", "TST_kelmtype")); + + Assert.assertNotNull(res, + "Method getFilteredList must not return null."); + Assert.assertEquals(res.size(), 2, "Number of found objects is wrong."); + + // //////////////////////////////////////////////////// + // Call DAO's getFilteredList method with defined order parameter. + res = _knowledgeElementDAO.getFilteredList("type", Restrictions.eq( + "name", "TST_kelmtype"), Order.asc("title")); + + Assert.assertNotNull(res, + "Method getFilteredList must not return null."); + Assert.assertEquals(res.size(), 2, "Number of found objects is wrong."); + Assert.assertEquals(res.get(0).getIndex(), id, + "Sorting of results is not correct."); + Assert.assertEquals(res.get(1).getIndex(), id2, + "Sorting of results is not correct."); + + rollbackNestedTransaction(); + LOG.debug(">>>>> END testGetFilteredList()"); + } } -- 2.39.2