1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.student.r2.common.dao;
18
19 import java.lang.reflect.ParameterizedType;
20 import java.lang.reflect.Type;
21 import java.util.ArrayList;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Set;
25
26 import javax.persistence.EntityManager;
27 import javax.persistence.NoResultException;
28 import javax.persistence.NonUniqueResultException;
29 import javax.persistence.PersistenceContext;
30 import javax.persistence.Query;
31
32 import org.apache.commons.lang.StringUtils;
33 import org.kuali.student.r2.common.entity.PersistableEntity;
34 import org.kuali.student.r2.common.exceptions.DoesNotExistException;
35
36
37
38
39 public class GenericEntityDao<T extends PersistableEntity<String>> implements EntityDao<String,T> {
40
41
42
43
44 protected Class<T> entityClass;
45
46 @PersistenceContext
47 protected EntityManager em;
48
49 public GenericEntityDao() {
50 entityClass = getEntityClass();
51 }
52
53 @Override
54 public T find(String primaryKey) {
55 return em.find(entityClass, primaryKey);
56 }
57
58 @Override
59 public List<T> findByIds(String primaryKeyMemberName, List<String> primaryKeys) throws DoesNotExistException {
60
61
62 if (primaryKeys.isEmpty())
63 return new ArrayList<T>();
64
65 Set<String>primaryKeySet = new HashSet<String>(primaryKeys.size());
66
67 primaryKeySet.addAll(primaryKeys);
68
69 String queryString = "from " + entityClass.getSimpleName() + " where "
70 + primaryKeyMemberName + " in (:ids)";
71
72 List<T> resultList = em.createQuery(queryString)
73 .setParameter("ids", primaryKeySet).getResultList();
74
75 verifyResults(resultList, primaryKeySet);
76
77 return resultList;
78 }
79
80
81
82
83
84
85
86
87 public boolean entityExists (String primaryKey) {
88
89
90 Query q = em.createQuery("select id from " + entityClass.getSimpleName() + " where id = :key").setParameter("key", primaryKey);
91
92 Object result;
93 try {
94 result = q.getSingleResult();
95 }
96 catch (NonUniqueResultException e) {
97
98 return false;
99 }
100 catch (NoResultException e) {
101
102 return false;
103 }
104
105
106 return true;
107
108 }
109 protected void verifyResults(List<T> resultList, Set<String> primaryKeys) throws DoesNotExistException {
110
111 if (resultList.size() == 0)
112 throw new DoesNotExistException("No data was found for : " + StringUtils.join(primaryKeys, ", "));
113
114 else if (resultList.size() != primaryKeys.size()) {
115
116 Set<String> unmatchedKeySet = new HashSet<String> ();
117
118 unmatchedKeySet.addAll(primaryKeys);
119
120 for (T t : resultList) {
121
122 unmatchedKeySet.remove(t.getId());
123 }
124
125 throw new DoesNotExistException("Missing data for : " + StringUtils.join(unmatchedKeySet.iterator(), ", "));
126
127 }
128 }
129
130 @Override
131 public List<T> findByIds(List<String> primaryKeys) throws DoesNotExistException {
132
133 if(primaryKeys.size() >= 1000){
134 return this.findByIdsMaxKeys(primaryKeys);
135 } else {
136 return this.findByIds("id", primaryKeys);
137 }
138 }
139
140
141
142
143
144
145
146
147 protected List<T> findByIdsMaxKeys(List<String> primaryKeys) throws DoesNotExistException {
148 List<T> resultList = new ArrayList<T>();
149
150
151 if (primaryKeys.isEmpty())
152 return new ArrayList<T>();
153
154 Set<String>primaryKeySet = new HashSet<String>(primaryKeys.size());
155
156 primaryKeySet.addAll(primaryKeys);
157
158
159 for (String primaryKey : primaryKeys) {
160
161 T entity = find(primaryKey);
162
163 if (entity == null) {
164
165 throw new DoesNotExistException("No data was found for :" + primaryKey);
166
167 }
168 resultList.add(entity);
169 }
170
171 verifyResults (resultList, primaryKeySet);
172
173 return resultList;
174 }
175
176
177 @Override
178 @SuppressWarnings("unchecked")
179 public List<T> findAll() {
180 return (List<T>) em.createQuery("from " + entityClass.getSimpleName()).getResultList();
181 }
182
183 @Override
184 public void persist(T entity) {
185 em.persist(entity);
186 }
187
188 @Override
189 public void update(T entity) {
190 em.merge(entity);
191 }
192
193 @Override
194 public void remove(T entity) {
195 em.remove(entity);
196 }
197
198 @Override
199 public T merge(T entity) {
200
201 if (em.contains(entity))
202 em.detach(entity);
203
204 return em.merge(entity);
205 }
206
207 @SuppressWarnings("unchecked")
208 protected <C extends T> Class<C> getEntityClass() {
209 if (entityClass == null) {
210 entityClass = (Class<T>) getEntityType(this);
211 }
212 return (Class<C>) entityClass;
213 }
214
215 private Type getEntityType(Object object) {
216 Type type = object.getClass().getGenericSuperclass();
217 if (type instanceof ParameterizedType) {
218 ParameterizedType paramType = (ParameterizedType) type;
219 Type result = paramType.getActualTypeArguments()[0];
220 return result;
221 } else {
222 throw new IllegalArgumentException("Could not guess entity type by reflection.");
223 }
224 }
225
226 @Override
227 public void setEm(EntityManager em) {
228 this.em = em;
229 }
230
231 @Override
232 public EntityManager getEm() {
233 return em;
234 }
235
236
237 }