View Javadoc

1   package org.appfuse.dao.hibernate;
2   
3   import org.apache.commons.logging.Log;
4   import org.apache.commons.logging.LogFactory;
5   import org.apache.lucene.analysis.Analyzer;
6   import org.apache.lucene.analysis.standard.StandardAnalyzer;
7   import org.apache.lucene.queryParser.ParseException;
8   import org.apache.lucene.util.Version;
9   import org.appfuse.dao.GenericDao;
10  import org.appfuse.dao.SearchException;
11  import org.hibernate.*;
12  import org.hibernate.search.FullTextSession;
13  import org.hibernate.search.Search;
14  import org.springframework.beans.factory.annotation.Autowired;
15  import org.springframework.beans.factory.annotation.Required;
16  import org.springframework.orm.ObjectRetrievalFailureException;
17  
18  import javax.annotation.Resource;
19  import java.io.Serializable;
20  import java.util.*;
21  
22  /**
23   * This class serves as the Base class for all other DAOs - namely to hold
24   * common CRUD methods that they might all use. You should only need to extend
25   * this class when your require custom CRUD logic.
26   * <p/>
27   * <p>To register this class in your Spring context file, use the following XML.
28   * <pre>
29   *      &lt;bean id="fooDao" class="org.appfuse.dao.hibernate.GenericDaoHibernate"&gt;
30   *          &lt;constructor-arg value="org.appfuse.model.Foo"/&gt;
31   *      &lt;/bean&gt;
32   * </pre>
33   *
34   * @param <T>  a type variable
35   * @param <PK> the primary key for that type
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   */
40  public class GenericDaoHibernate<T, PK extends Serializable> implements GenericDao<T, PK> {
41      /**
42       * Log variable for all child classes. Uses LogFactory.getLog(getClass()) from Commons Logging
43       */
44      protected final Log log = LogFactory.getLog(getClass());
45      private Class<T> persistentClass;
46      @Resource
47      private SessionFactory sessionFactory;
48      private Analyzer defaultAnalyzer;
49  
50      /**
51       * Constructor that takes in a class to see which type of entity to persist.
52       * Use this constructor when subclassing.
53       *
54       * @param persistentClass the class type you'd like to persist
55       */
56      public GenericDaoHibernate(final Class<T> persistentClass) {
57          this.persistentClass = persistentClass;
58          defaultAnalyzer = new StandardAnalyzer(Version.LUCENE_36);
59      }
60  
61      /**
62       * Constructor that takes in a class and sessionFactory for easy creation of DAO.
63       *
64       * @param persistentClass the class type you'd like to persist
65       * @param sessionFactory  the pre-configured Hibernate SessionFactory
66       */
67      public GenericDaoHibernate(final Class<T> persistentClass, SessionFactory sessionFactory) {
68          this.persistentClass = persistentClass;
69          this.sessionFactory = sessionFactory;
70          defaultAnalyzer = new StandardAnalyzer(Version.LUCENE_36);
71      }
72  
73      public SessionFactory getSessionFactory() {
74          return this.sessionFactory;
75      }
76  
77      public Session getSession() throws HibernateException {
78          Session sess = getSessionFactory().getCurrentSession();
79          if (sess == null) {
80              sess = getSessionFactory().openSession();
81          }
82          return sess;
83      }
84  
85      @Autowired
86      @Required
87      public void setSessionFactory(SessionFactory sessionFactory) {
88          this.sessionFactory = sessionFactory;
89      }
90  
91      /**
92       * {@inheritDoc}
93       */
94      @SuppressWarnings("unchecked")
95      public List<T> getAll() {
96          Session sess = getSession();
97          return sess.createCriteria(persistentClass).list();
98      }
99  
100     /**
101      * {@inheritDoc}
102      */
103     @SuppressWarnings("unchecked")
104     public List<T> getAllDistinct() {
105         Collection<T> result = new LinkedHashSet<T>(getAll());
106         return new ArrayList<T>(result);
107     }
108 
109     /**
110      * {@inheritDoc}
111      */
112     public List<T> search(String searchTerm) throws SearchException {
113         Session sess = getSession();
114         FullTextSession txtSession = Search.getFullTextSession(sess);
115 
116         org.apache.lucene.search.Query qry;
117         try {
118             qry = HibernateSearchTools.generateQuery(searchTerm, this.persistentClass, sess, defaultAnalyzer);
119         } catch (ParseException ex) {
120             throw new SearchException(ex);
121         }
122         org.hibernate.search.FullTextQuery hibQuery = txtSession.createFullTextQuery(qry,
123                 this.persistentClass);
124         return hibQuery.list();
125     }
126 
127     /**
128      * {@inheritDoc}
129      */
130     @SuppressWarnings("unchecked")
131     public T get(PK id) {
132         Session sess = getSession();
133         IdentifierLoadAccess byId = sess.byId(persistentClass);
134         T entity = (T) byId.load(id);
135 
136         if (entity == null) {
137             log.warn("Uh oh, '" + this.persistentClass + "' object with id '" + id + "' not found...");
138             throw new ObjectRetrievalFailureException(this.persistentClass, id);
139         }
140 
141         return entity;
142     }
143 
144     /**
145      * {@inheritDoc}
146      */
147     @SuppressWarnings("unchecked")
148     public boolean exists(PK id) {
149         Session sess = getSession();
150         IdentifierLoadAccess byId = sess.byId(persistentClass);
151         T entity = (T) byId.load(id);
152         return entity != null;
153     }
154 
155     /**
156      * {@inheritDoc}
157      */
158     @SuppressWarnings("unchecked")
159     public T save(T object) {
160         Session sess = getSession();
161         return (T) sess.merge(object);
162     }
163 
164     /**
165      * {@inheritDoc}
166      */
167     public void remove(T object) {
168         Session sess = getSession();
169         sess.delete(object);
170     }
171 
172     /**
173      * {@inheritDoc}
174      */
175     public void remove(PK id) {
176         Session sess = getSession();
177         IdentifierLoadAccess byId = sess.byId(persistentClass);
178         T entity = (T) byId.load(id);
179         sess.delete(entity);
180     }
181 
182     /**
183      * {@inheritDoc}
184      */
185     @SuppressWarnings("unchecked")
186     public List<T> findByNamedQuery(String queryName, Map<String, Object> queryParams) {
187         Session sess = getSession();
188         Query namedQuery = sess.getNamedQuery(queryName);
189         for (String s : queryParams.keySet()) {
190             Object val = queryParams.get(s);
191             if (val instanceof Collection) {
192                 namedQuery.setParameterList(s, (Collection) val);
193             } else {
194                 namedQuery.setParameter(s, val);
195             }
196         }
197         return namedQuery.list();
198     }
199 
200     /**
201      * {@inheritDoc}
202      */
203     public void reindex() {
204         HibernateSearchTools.reindex(persistentClass, getSessionFactory().getCurrentSession());
205     }
206 
207 
208     /**
209      * {@inheritDoc}
210      */
211     public void reindexAll(boolean async) {
212         HibernateSearchTools.reindexAll(async, getSessionFactory().getCurrentSession());
213     }
214 }