001 // Copyright 2008 Thiago H. de Paula Figueiredo
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package br.com.arsmachina.dao.hibernate;
016
017 import java.io.Serializable;
018 import java.lang.reflect.ParameterizedType;
019 import java.lang.reflect.Type;
020
021 import org.hibernate.SessionFactory;
022 import org.hibernate.classic.Session;
023 import org.hibernate.metadata.ClassMetadata;
024
025 /**
026 * Superclass of both {@link ReadableDAOImpl} and {@link WriteableDAOImpl}.
027 *
028 * @author Thiago H. de Paula Figueiredo
029 * @param <T> the entity class related to this DAO.
030 * @param <K> the type of the field that represents the entity class' primary key.
031 */
032 public class BaseHibernateDAO<T, K extends Serializable> {
033
034 private final SessionFactory sessionFactory;
035
036 private final Class<T> entityClass;
037
038 private final ClassMetadata classMetadata;
039
040 private final String primaryKeyPropertyName;
041
042 /**
043 * Constructor that takes a {@link Class} and a {@link SessionFactory}.
044 *
045 * @param clasz a {@link Class}.
046 * @param sessionFactory a {@link SessionFactory}. It cannot be null.
047 */
048 @SuppressWarnings("unchecked")
049 public BaseHibernateDAO(SessionFactory sessionFactory) {
050 this(null, sessionFactory);
051 }
052
053 /**
054 * Constructor that takes a {@link Class} and a {@link SessionFactory}.
055 *
056 * @param clasz a {@link Class}.
057 * @param sessionFactory a {@link SessionFactory}. It cannot be null.
058 */
059 @SuppressWarnings("unchecked")
060 public BaseHibernateDAO(Class<T> clasz, SessionFactory sessionFactory) {
061
062 if (sessionFactory == null) {
063 throw new IllegalArgumentException("Parameter sessionFactory cannot be null");
064 }
065
066 this.sessionFactory = sessionFactory;
067
068 entityClass = clasz != null ? clasz : extractEntityClassFromHierarchy();
069 classMetadata = sessionFactory.getClassMetadata(getEntityClass());
070
071 if (getClassMetadata() == null) {
072 throw new RuntimeException("Class " + getEntityClass().getName() + " is not mapped");
073 }
074
075 primaryKeyPropertyName = getClassMetadata().getIdentifierPropertyName();
076
077 assert getEntityClass() != null;
078 assert getClassMetadata() != null;
079 assert getPrimaryKeyPropertyName() != null;
080
081 }
082
083 /**
084 * @return
085 */
086 @SuppressWarnings("unchecked")
087 private Class<T> extractEntityClassFromHierarchy() {
088
089 final Type genericSuperclass = getClass().getGenericSuperclass();
090 final ParameterizedType parameterizedType = ((ParameterizedType) genericSuperclass);
091 return (Class<T>) parameterizedType.getActualTypeArguments()[0];
092
093 }
094
095 /**
096 * Returns the entity class handled by this DAO.
097 *
098 * @return a {@link Class<T>}.
099 */
100 protected final Class<T> getEntityClass() {
101 return entityClass;
102 }
103
104 /**
105 * Returns a {@link Session}. This implementation returns
106 * {@link SessionFactory#getCurrentSession()} and can be overriden if needed.
107 *
108 * @return a {@link Session}.
109 */
110 protected Session getSession() {
111 return getSessionFactory().getCurrentSession();
112 }
113
114 /**
115 * Returns this DAO's {@link SessionFactory}.
116 *
117 * @return a {@link SessionFactory}.
118 */
119 protected final SessionFactory getSessionFactory() {
120 return sessionFactory;
121 }
122
123 /**
124 * Returns the {@link ClassMetadata} for the corresponding entity class.
125 *
126 * @return a {@link ClassMetadata}.
127 */
128 protected final ClassMetadata getClassMetadata() {
129 return classMetadata;
130 }
131
132 /**
133 * Returns the name of the id property.
134 *
135 * @return a {@link String}.
136 */
137 protected String getPrimaryKeyPropertyName() {
138 return primaryKeyPropertyName;
139 }
140
141 }