View Javadoc

1   package org.appfuse.dao.jpa;
2   
3   import org.apache.commons.logging.Log;
4   import org.apache.commons.logging.LogFactory;
5   import org.appfuse.dao.GenericDao;
6   import org.appfuse.dao.SearchException;
7   
8   import javax.persistence.EntityManager;
9   import javax.persistence.EntityNotFoundException;
10  import javax.persistence.PersistenceContext;
11  import java.io.Serializable;
12  import java.util.ArrayList;
13  import java.util.Collection;
14  import java.util.LinkedHashSet;
15  import java.util.List;
16  import org.apache.lucene.analysis.Analyzer;
17  import org.apache.lucene.analysis.standard.StandardAnalyzer;
18  import org.apache.lucene.queryParser.ParseException;
19  import org.apache.lucene.util.Version;
20  import org.hibernate.search.jpa.FullTextEntityManager;
21  import org.hibernate.search.jpa.Search;
22  
23  /**
24   * This class serves as the Base class for all other DAOs - namely to hold
25   * common CRUD methods that they might all use. You should only need to extend
26   * this class when your require custom CRUD logic.
27   *
28   * <p>To register this class in your Spring context file, use the following XML.
29   * <pre>
30   *      &lt;bean id="fooDao" class="org.appfuse.dao.hibernate.GenericDaoJpaHibernate"&gt;
31   *          &lt;constructor-arg value="org.appfuse.model.Foo"/&gt;
32   *          &lt;property name="sessionFactory" ref="sessionFactory"/&gt;
33   *      &lt;/bean&gt;
34   * </pre>
35   *
36   * @author <a href="mailto:bwnoll@gmail.com">Bryan Noll</a>
37   *      Updated by jgarcia: update hibernate3 to hibernate4
38   * @author jgarcia (update: added full text search + reindexing)
39   * @param <T> a type variable
40   * @param <PK> the primary key for that type
41   */
42  public class GenericDaoJpa<T, PK extends Serializable> implements GenericDao<T, PK> {
43      /**
44       * Log variable for all child classes. Uses LogFactory.getLog(getClass()) from Commons Logging
45       */
46      protected final Log log = LogFactory.getLog(getClass());
47  
48      public static final String PERSISTENCE_UNIT_NAME = "ApplicationEntityManager";
49  
50      /**
51       * Entity manager, injected by Spring using @PersistenceContext annotation on setEntityManager()
52       */
53      @PersistenceContext(unitName=PERSISTENCE_UNIT_NAME)
54      private EntityManager entityManager;
55      private Class<T> persistentClass;
56      private Analyzer defaultAnalyzer;
57  
58      /**
59       * Constructor that takes in a class to see which type of entity to persist.
60       * Use this constructor when subclassing or using dependency injection.
61       * @param persistentClass the class type you'd like to persist
62       */
63      public GenericDaoJpa(final Class<T> persistentClass) {
64          this.persistentClass = persistentClass;
65          defaultAnalyzer = new StandardAnalyzer(Version.LUCENE_36);
66      }
67  
68      /**
69       * Constructor that takes in a class to see which type of entity to persist.
70       * Use this constructor when subclassing or using dependency injection.
71       * @param persistentClass the class type you'd like to persist
72       * @param entityManager the configured EntityManager for JPA implementation.
73       */
74      public GenericDaoJpa(final Class<T> persistentClass, EntityManager entityManager) {
75          this.persistentClass = persistentClass;
76          this.entityManager = entityManager;
77          defaultAnalyzer = new StandardAnalyzer(Version.LUCENE_36);
78      }
79  
80      public EntityManager getEntityManager() {
81          return this.entityManager;
82      }
83  
84      /**
85       * {@inheritDoc}
86       */
87      @SuppressWarnings("unchecked")
88      public List<T> getAll() {
89          return this.entityManager.createQuery(
90                  "select obj from " + this.persistentClass.getName() + " obj")
91                  .getResultList();
92      }
93  
94      /**
95       * {@inheritDoc}
96       */
97      @SuppressWarnings("unchecked")
98      public List<T> getAllDistinct() {
99          Collection result = new LinkedHashSet(getAll());
100         return new ArrayList(result);
101     }
102 
103     /**
104      * {@inheritDoc}
105      */
106     public T get(PK id) {
107         T entity = this.entityManager.find(this.persistentClass, id);
108 
109         if (entity == null) {
110             String msg = "Uh oh, '" + this.persistentClass + "' object with id '" + id + "' not found...";
111             log.warn(msg);
112             throw new EntityNotFoundException(msg);
113         }
114 
115         return entity;
116     }
117 
118     /**
119      * {@inheritDoc}
120      */
121     public boolean exists(PK id) {
122         T entity = this.entityManager.find(this.persistentClass, id);
123         return entity != null;
124     }
125 
126     /**
127      * {@inheritDoc}
128      */
129     public T save(T object) {
130         return this.entityManager.merge(object);
131     }
132 
133     /**
134      * {@inheritDoc}
135      */
136     public void remove(T object) {
137         entityManager.remove(entityManager.contains(object) ? object : entityManager.merge(object)); 
138     } 
139 
140     /**
141      * {@inheritDoc}
142      */
143     public void remove(PK id) {
144         this.entityManager.remove(this.get(id));
145     }
146 
147     public List<T> search(String searchTerm) throws SearchException {
148         FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
149         org.apache.lucene.search.Query qry;
150         try {
151             qry = HibernateSearchJpaTools.generateQuery(searchTerm, this.persistentClass, entityManager, defaultAnalyzer);
152         } catch (ParseException ex) {
153             throw new SearchException(ex);
154         }
155         org.hibernate.search.jpa.FullTextQuery hibQuery = fullTextEntityManager.createFullTextQuery(qry, this.persistentClass);
156         // filter search results by owner.id value:
157         // hibQuery.enableFullTextFilter("owned").setParameter("ownerId", owner.getId().toString());
158         return hibQuery.getResultList();
159     }
160 
161     /**
162      * {@inheritDoc}
163      */
164     public void reindex() {
165         HibernateSearchJpaTools.reindex(persistentClass, getEntityManager());
166     }
167 
168 
169     /**
170      * {@inheritDoc}
171      */
172     public void reindexAll(boolean async) {
173         HibernateSearchJpaTools.reindexAll(async, getEntityManager());
174     }
175 }