From: <gca...@us...> - 2010-06-07 07:11:44
|
Revision: 2623 http://openutils.svn.sourceforge.net/openutils/?rev=2623&view=rev Author: gcatania Date: 2010-06-07 07:11:35 +0000 (Mon, 07 Jun 2010) Log Message: ----------- proposed fix to BSHD-2 (wip) Modified Paths: -------------- trunk/openutils-bshd5/src/main/java/it/openutils/dao/hibernate/HibernateDAOImpl.java trunk/openutils-bshd5/src/test/java/it/openutils/hibernate/test/HibernateDAOTest.java trunk/openutils-bshd5/src/test/java/it/openutils/hibernate/test/model/Person.java trunk/openutils-bshd5/src/test/resources/spring-tests.xml Added Paths: ----------- trunk/openutils-bshd5/src/main/java/it/openutils/hibernate/example/ExampleTree.java trunk/openutils-bshd5/src/test/resources/log4j.xml Modified: trunk/openutils-bshd5/src/main/java/it/openutils/dao/hibernate/HibernateDAOImpl.java =================================================================== --- trunk/openutils-bshd5/src/main/java/it/openutils/dao/hibernate/HibernateDAOImpl.java 2010-06-03 15:14:36 UTC (rev 2622) +++ trunk/openutils-bshd5/src/main/java/it/openutils/dao/hibernate/HibernateDAOImpl.java 2010-06-07 07:11:35 UTC (rev 2623) @@ -25,7 +25,7 @@ package it.openutils.dao.hibernate; -import it.openutils.hibernate.example.EnhancedExample; +import it.openutils.hibernate.example.ExampleTree; import it.openutils.hibernate.example.FilterMetadata; import java.io.Serializable; @@ -36,6 +36,7 @@ import java.util.Map; import org.aopalliance.aop.AspectException; +import org.apache.commons.collections.CollectionUtils; import org.hibernate.Criteria; import org.hibernate.Hibernate; import org.hibernate.HibernateException; @@ -714,7 +715,8 @@ @SuppressWarnings("unchecked") public List<T> doInHibernate(Session ses) throws HibernateException { - Criteria crit = ses.createCriteria(filter.getClass()); + // Criteria crit = ses.createCriteria(filter.getClass()); + Criteria crit = new ExampleTree(filter).create(ses); crit.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); crit.setMaxResults(maxResults); crit.setFirstResult(maxResults * page); @@ -729,15 +731,15 @@ } } } - EnhancedExample.create(crit, filter, metadata); - if (additionalCriteria != null) + // EnhancedExample.create(crit, filter, metadata); + if (CollectionUtils.isNotEmpty(additionalCriteria)) { for (Criterion criterion : additionalCriteria) { crit.add(criterion); } } - if (properties != null) + if (CollectionUtils.isNotEmpty(properties)) { ProjectionList projectionList = Projections.projectionList(); Added: trunk/openutils-bshd5/src/main/java/it/openutils/hibernate/example/ExampleTree.java =================================================================== --- trunk/openutils-bshd5/src/main/java/it/openutils/hibernate/example/ExampleTree.java (rev 0) +++ trunk/openutils-bshd5/src/main/java/it/openutils/hibernate/example/ExampleTree.java 2010-06-07 07:11:35 UTC (rev 2623) @@ -0,0 +1,103 @@ +package it.openutils.hibernate.example; + +import org.hibernate.Criteria; +import org.hibernate.EntityMode; +import org.hibernate.Hibernate; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.criterion.Example; +import org.hibernate.metadata.ClassMetadata; +import org.hibernate.type.AssociationType; +import org.hibernate.type.Type; + + +/** + * facility to create subcriteria and examples for associations of an input entity + * @author gcatania + */ +public class ExampleTree +{ + + // TODO: allow specification of parameters to pass along to created examples, internally save association paths, + // fail fast on null entity; check for parent entities (currently the parameter is unused) to avoid infinite loops + // on parent/child references + + private final Object entity; + + /** + * builds an instance of {@code ExampleTree} associated with the input entity + * @param entity the example entity + */ + public ExampleTree(Object entity) + { + this.entity = entity; + } + + /** + * creates a criteria with the input session, adds to it an example for the input entity, and creates subcriteria + * and related examples for non-null property values of type {@link AssociationType} on the entity this example tree + * was initialized with + * @param ses the session + * @return a criteria for this example tree + */ + public Criteria create(Session ses) + { + return appendTo(ses.createCriteria(Hibernate.getClass(entity)), ses); + } + + /** + * appends examples and subcriteria, created for the entity this example tree was initialized with, to the input + * criteria, and then returns it + * @param crit the criteria to append to + * @param ses the session + * @return the input criteria with the added subcriteria and examples + */ + public Criteria appendTo(Criteria crit, Session ses) + { + new ExampleTreeWalker(ses).createSubExamples(crit, entity, null); + return crit; + } + + private static class ExampleTreeWalker + { + + private final SessionFactory sessionFactory; + + private EntityMode entityMode; + + public ExampleTreeWalker(Session session) + { + sessionFactory = session.getSessionFactory(); + entityMode = session.getEntityMode(); + } + + public void createSubExamples(Criteria crit, Object entity, Object parentEntity) + { + crit.add(Example.create(entity)); + ClassMetadata classMetadata = sessionFactory.getClassMetadata(Hibernate.getClass(entity)); + Type[] types = classMetadata.getPropertyTypes(); + String[] names = classMetadata.getPropertyNames(); + for (int i = 0; i < types.length; i++) + { + Type propertyType = types[i]; + if (!propertyType.isAssociationType()) + { + // handled by Example.create() + continue; + } + String propertyName = names[i]; + Object propertyValue = classMetadata.getPropertyValue(entity, propertyName, entityMode); + if (propertyValue == null) + { + // skip null values (TODO: allow specifications of which values to exclude, also see + // EnhancedExample.containsSomething() + continue; + } + + Criteria subCriteria = crit.createCriteria(propertyName); + createSubExamples(subCriteria, propertyValue, entity); + } + } + } + +} Property changes on: trunk/openutils-bshd5/src/main/java/it/openutils/hibernate/example/ExampleTree.java ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Modified: trunk/openutils-bshd5/src/test/java/it/openutils/hibernate/test/HibernateDAOTest.java =================================================================== --- trunk/openutils-bshd5/src/test/java/it/openutils/hibernate/test/HibernateDAOTest.java 2010-06-03 15:14:36 UTC (rev 2622) +++ trunk/openutils-bshd5/src/test/java/it/openutils/hibernate/test/HibernateDAOTest.java 2010-06-07 07:11:35 UTC (rev 2623) @@ -29,12 +29,16 @@ import it.openutils.hibernate.test.model.Address; import it.openutils.hibernate.test.model.FullName; import it.openutils.hibernate.test.model.Person; +import it.openutils.hibernate.test.model.Wish; +import java.util.Collections; import java.util.List; +import org.hibernate.Hibernate; +import org.hibernate.criterion.Example; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; +import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests; import org.testng.Assert; import org.testng.annotations.Test; @@ -43,7 +47,7 @@ * @author gcatania */ @ContextConfiguration(locations = "/spring-tests.xml") -public class HibernateDAOTest extends AbstractTestNGSpringContextTests +public class HibernateDAOTest extends AbstractTransactionalTestNGSpringContextTests { @Autowired @@ -74,23 +78,55 @@ Assert.assertEquals(person, savedPerson); } - /** - * fails because of BSHD-5 - */ - @Test(enabled = false) + @Test public void testFindFilteredFirst() { personDAO.save(fifteenYearsOld()); List<Person> found = personDAO.findFiltered(new Person(new FullName(null, "Jones"), null, null, null)); + Assert.assertTrue(found.size() > 0, "No persons found."); + } + + @Test + public void testExampleBasic() + { + personDAO.save(fifteenYearsOld()); + Person outsideFilter = fifteenYearsOld(); + outsideFilter.getName().setFamilyName("Mahoney"); + personDAO.save(outsideFilter); + Person filter = new Person(new FullName(null, "Jones"), null, null, null); + List<Person> foundByExample = personDAO.find(Collections.singletonList(Example.create(filter))); + Assert.assertNotNull(foundByExample); + Assert.assertEquals(foundByExample.size(), 1); + Assert.assertEquals(foundByExample.get(0).getName().getFamilyName(), "Jones"); + + List<Person> found = personDAO.findFiltered(filter); Assert.assertNotNull(found); - if (found.size() == 0) - { - Assert.fail("No persons found"); - } - for (Person p : found) - { - System.out.println(p.toString()); - } + Assert.assertEquals(found.size(), 1); + Assert.assertEquals(found.get(0).getName().getFamilyName(), "Jones"); } + @Test + public void testExampleAssociations() + { + Person fifteenYearsOld = fifteenYearsOld(); + fifteenYearsOld.setWish(new Wish(fifteenYearsOld, "because he's young")); + personDAO.save(fifteenYearsOld); + Person another = fifteenYearsOld(); + another.setWish(new Wish(another, "because he's a nerd")); + personDAO.save(another); + + Person filter = new Person(); + filter.setWish(new Wish(null, "because he's young")); + List<Person> foundByExample = personDAO.find(Collections.singletonList(Example.create(filter))); + Hibernate.initialize(foundByExample); + Assert.assertNotNull(foundByExample); + Assert.assertEquals(foundByExample.size(), 2); + + List<Person> found = personDAO.findFiltered(filter); + Hibernate.initialize(found); + Assert.assertNotNull(found); + Assert.assertEquals(found.size(), 1); + Assert.assertEquals(found.get(0).getWish().getReason(), "because he's young"); + } + } Modified: trunk/openutils-bshd5/src/test/java/it/openutils/hibernate/test/model/Person.java =================================================================== --- trunk/openutils-bshd5/src/test/java/it/openutils/hibernate/test/model/Person.java 2010-06-03 15:14:36 UTC (rev 2622) +++ trunk/openutils-bshd5/src/test/java/it/openutils/hibernate/test/model/Person.java 2010-06-07 07:11:35 UTC (rev 2623) @@ -60,7 +60,7 @@ @ManyToOne(cascade = CascadeType.ALL) private Address fiscalAddress; - @OneToOne + @OneToOne(cascade = CascadeType.ALL) private Wish wish; public Person() Added: trunk/openutils-bshd5/src/test/resources/log4j.xml =================================================================== --- trunk/openutils-bshd5/src/test/resources/log4j.xml (rev 0) +++ trunk/openutils-bshd5/src/test/resources/log4j.xml 2010-06-07 07:11:35 UTC (rev 2623) @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> +<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> + <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%p - %C{1}.%M(%L) | %m%n" /> + </layout> + </appender> + <logger name="org.apache"> + <level value="WARN" /> + </logger> + <logger name="org.springframework"> + <level value="INFO" /> + </logger> + <root> + <level value="INFO" /> + <appender-ref ref="CONSOLE" /> + </root> +</log4j:configuration> \ No newline at end of file Property changes on: trunk/openutils-bshd5/src/test/resources/log4j.xml ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Modified: trunk/openutils-bshd5/src/test/resources/spring-tests.xml =================================================================== --- trunk/openutils-bshd5/src/test/resources/spring-tests.xml 2010-06-03 15:14:36 UTC (rev 2622) +++ trunk/openutils-bshd5/src/test/resources/spring-tests.xml 2010-06-07 07:11:35 UTC (rev 2623) @@ -28,4 +28,7 @@ </props> </property> </bean> + <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> + <property name="sessionFactory" ref="sessionFactory" /> + </bean> </beans> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |