View Javadoc

1   // Copyright 2007-2008 Thiago H. de Paula Figueiredo
2   //
3   // Licensed under the Apache License, Version 2.0 (the "License");
4   // you may not use this file except in compliance with the License.
5   // You may obtain a copy of the License at
6   //
7   //     http://www.apache.org/licenses/LICENSE-2.0
8   //
9   // Unless required by applicable law or agreed to in writing, software
10  // distributed under the License is distributed on an "AS IS" BASIS,
11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  // See the License for the specific language governing permissions and
13  // limitations under the License.
14  
15  package br.com.arsmachina.dao.hibernate;
16  
17  import java.io.Serializable;
18  import java.lang.reflect.ParameterizedType;
19  import java.lang.reflect.Type;
20  import java.util.List;
21  
22  import org.hibernate.Criteria;
23  import org.hibernate.SessionFactory;
24  import org.hibernate.classic.Session;
25  import org.hibernate.criterion.Example;
26  import org.hibernate.metadata.ClassMetadata;
27  
28  import br.com.arsmachina.dao.DAO;
29  import br.com.arsmachina.dao.SortCriterion;
30  
31  /**
32   * {@link AbstractDAO} implementation using Hibernate. All methods use {@link #getSession()} to get
33   * a {@link Session}. All methods delegate its calls to an internal {@link ReadableDAOImpl} or
34   * {@link WriteableDAOImpl} instance.
35   * 
36   * @author Thiago H. de Paula Figueiredo
37   * @param <T> the entity class related to this DAO.
38   * @param <K> the type of the field that represents the entity class' primary key.
39   */
40  public class GenericDAOImpl<T, K extends Serializable> implements DAO<T, K> {
41  
42  	final private InternalReadableDAOImpl readableDAO;
43  
44  	final private InternalWriteableDAOImpl writeableDAO;
45  
46  	/**
47  	 * Single public constructor.
48  	 * 
49  	 * @param sessionFactory a {@link SessionFactory}. It cannot be null.
50  	 */
51  	@SuppressWarnings("unchecked")
52  	public GenericDAOImpl(SessionFactory sessionFactory) {
53  
54  		if (sessionFactory == null) {
55  			throw new IllegalArgumentException("Parameter sessionFactory cannot be null");
56  		}
57  
58  		final Type genericSuperclass = getClass().getGenericSuperclass();
59  		final ParameterizedType parameterizedType = ((ParameterizedType) genericSuperclass);
60  		Class clasz = (Class<T>) parameterizedType.getActualTypeArguments()[0];
61  
62  		readableDAO = new InternalReadableDAOImpl(clasz, sessionFactory);
63  		writeableDAO = new InternalWriteableDAOImpl(clasz, sessionFactory);
64  
65  	}
66  
67  	/**
68  	 * Constructor made specifically for {@link ConcreteDAOImpl}. It shouldn't be used in
69  	 * any other class. 
70  	 * 
71  	 * @param clasz the entity class. It cannot be null.
72  	 * @param sessionFactory a {@link SessionFactory}. It cannot be null.
73  	 */
74  	GenericDAOImpl(Class<T> clasz, SessionFactory sessionFactory) {
75  		
76  		if (clasz == null) {
77  			throw new IllegalArgumentException("Parameter clasz cannot be null");
78  		}
79  		
80  		if (sessionFactory == null) {
81  			throw new IllegalArgumentException("Parameter sessionFactory cannot be null");
82  		}
83  		
84  		readableDAO = new InternalReadableDAOImpl(clasz, sessionFactory);
85  		writeableDAO = new InternalWriteableDAOImpl(clasz, sessionFactory);
86  		
87  	}
88  
89  	public int countAll() {
90  		return readableDAO.countAll();
91  	}
92  
93  	public List<T> findAll() {
94  		return readableDAO.findAll();
95  	}
96  
97  	public List<T> findAll(int firstResult, int maximumResults, SortCriterion... sortingConstraints) {
98  		return readableDAO.findAll(firstResult, maximumResults, sortingConstraints);
99  	}
100 
101 	public List<T> findByExample(T example) {
102 		return readableDAO.findByExample(example);
103 	}
104 
105 	public T findById(K id) {
106 		return readableDAO.findById(id);
107 	}
108 
109 	public List<T> findByIds(K... ids) {
110 		return readableDAO.findByIds(ids);
111 	}
112 
113 	public void refresh(T object) {
114 		readableDAO.refresh(object);
115 	}
116 
117 	public void delete(T object) {
118 		writeableDAO.delete(object);
119 	}
120 
121 	public void delete(K id) {
122 		writeableDAO.delete(id);
123 	}
124 
125 	public void evict(T object) {
126 		writeableDAO.evict(object);
127 	}
128 
129 	public boolean isPersistent(T object) {
130 		return writeableDAO.isPersistent(object);
131 	}
132 
133 	public void save(T object) {
134 		writeableDAO.save(object);
135 	}
136 
137 	public T update(T object) {
138 		return writeableDAO.update(object);
139 	}
140 
141 	public T reattach(T object) {
142 		return readableDAO.reattach(object);
143 	}
144 
145 	public SortCriterion[] getDefaultSortCriteria() {
146 		return readableDAO.getDefaultSortCriteria();
147 	}
148 
149 	/**
150 	 * Invokes <code>readableDAO.addSortCriteria()<code>.
151 	 * @param criteria
152 	 * @see br.com.arsmachina.dao.hibernate.ReadableDAOImpl#addSortCriteria(org.hibernate.Criteria)
153 	 */
154 	protected void addSortCriteria(Criteria criteria) {
155 		readableDAO.addSortCriteria(criteria);
156 	}
157 	
158 	
159 	
160 	/**
161 	 * Invokes <code>delegate.addSortCriteria()<code>.
162 	 * @param criteria
163 	 * @param sortCriteria
164 	 * @see br.com.arsmachina.dao.hibernate.ReadableDAOImpl#addSortCriteria(org.hibernate.Criteria, br.com.arsmachina.dao.SortCriterion[])
165 	 */
166 	public final void addSortCriteria(Criteria criteria, SortCriterion... sortCriteria) {
167 		readableDAO.addSortCriteria(criteria, sortCriteria);
168 	}
169 
170 	/**
171 	 * Invokes <code>readableDAO.createCriteria()<code>.
172 	 * @return
173 	 * @see br.com.arsmachina.dao.hibernate.ReadableDAOImpl#createCriteria()
174 	 */
175 	protected Criteria createCriteria() {
176 		return readableDAO.createCriteria();
177 	}
178 	
179 	
180 
181 	/**
182 	 * Invokes <code>delegate.createCriteria()<code>.
183 	 * @param sortCriteria
184 	 * @return
185 	 * @see br.com.arsmachina.dao.hibernate.ReadableDAOImpl#createCriteria(br.com.arsmachina.dao.SortCriterion[])
186 	 */
187 	protected Criteria createCriteria(SortCriterion... sortCriteria) {
188 		return readableDAO.createCriteria(sortCriteria);
189 	}
190 	
191 	
192 
193 	/**
194 	 * Invokes <code>delegate.createCriteria()<code>.
195 	 * @param firstIndex
196 	 * @param maximumResults
197 	 * @param sortCriteria
198 	 * @return
199 	 * @see br.com.arsmachina.dao.hibernate.ReadableDAOImpl#createCriteria(int, int, br.com.arsmachina.dao.SortCriterion[])
200 	 */
201 	public Criteria createCriteria(int firstIndex, int maximumResults,
202 			SortCriterion... sortCriteria) {
203 		return readableDAO.createCriteria(firstIndex, maximumResults, sortCriteria);
204 	}
205 
206 	/**
207 	 * Invokes <code>readableDAO.createExample()<code>.
208 	 * @param entity
209 	 * @return
210 	 * @see br.com.arsmachina.dao.hibernate.ReadableDAOImpl#createExample(java.lang.Object)
211 	 */
212 	protected Example createExample(T entity) {
213 		return readableDAO.createExample(entity);
214 	}
215 
216 	/**
217 	 * Returns the entity class handled by this DAO.
218 	 * 
219 	 * @return a {@link Class<T>}.
220 	 */
221 	protected final Class<T> getEntityClass() {
222 		return readableDAO.getEntityClass();
223 	}
224 
225 	/**
226 	 * Returns a {@link Session}. This implementation returns
227 	 * {@link SessionFactory#getCurrentSession()} and can be overriden if needed.
228 	 * 
229 	 * @return a {@link Session}.
230 	 */
231 	protected Session getSession() {
232 		return getSessionFactory().getCurrentSession();
233 	}
234 
235 	/**
236 	 * Returns this DAO's {@link SessionFactory}.
237 	 * 
238 	 * @return a {@link SessionFactory}.
239 	 */
240 	protected final SessionFactory getSessionFactory() {
241 		return readableDAO.getSessionFactory();
242 	}
243 
244 	/**
245 	 * Returns the {@link ClassMetadata} for the corresponding entity class.
246 	 * 
247 	 * @return a {@link ClassMetadata}.
248 	 */
249 	final protected ClassMetadata getClassMetadata() {
250 		return readableDAO.getClassMetadata();
251 	}
252 
253 	/**
254 	 * Returns the name of the property.
255 	 * 
256 	 * @return a {@link String}.
257 	 */
258 	public String getPrimaryKeyPropertyName() {
259 		return readableDAO.getPrimaryKeyPropertyName();
260 	}
261 
262 	/**
263 	 * Concrete {@link ReadableDAOImpl} subclass.
264 	 * 
265 	 * @author Thiago H. de Paula Figueiredo
266 	 * @param <T>
267 	 * @param <K>
268 	 */
269 	private final class InternalReadableDAOImpl extends ReadableDAOImpl<T, K> {
270 
271 		public InternalReadableDAOImpl(Class<T> clasz, SessionFactory sessionFactory) {
272 			super(clasz, sessionFactory);
273 		}
274 
275 	}
276 
277 	/**
278 	 * Concrete {@link WriteableDAOImpl} subclass.
279 	 * 
280 	 * @author Thiago H. de Paula Figueiredo
281 	 * @param <T>
282 	 * @param <K>
283 	 */
284 	private final class InternalWriteableDAOImpl extends WriteableDAOImpl<T, K> {
285 
286 		public InternalWriteableDAOImpl(Class<T> clasz, SessionFactory sessionFactory) {
287 			super(clasz, sessionFactory);
288 		}
289 
290 	}
291 
292 }