1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.util.jpa;
35
36 import org.apache.logging.log4j.LogManager;
37 import org.apache.logging.log4j.Logger;
38 import org.springframework.dao.DataAccessResourceFailureException;
39
40 import org.springframework.orm.jpa.EntityManagerFactoryUtils;
41
42 import org.springframework.transaction.support.TransactionSynchronizationManager;
43
44 import java.lang.reflect.ParameterizedType;
45
46 import java.util.List;
47
48 import javax.persistence.EntityManager;
49 import javax.persistence.EntityManagerFactory;
50 import javax.persistence.Query;
51
52
53
54
55
56
57
58
59
60 public abstract class JPAGenericDAO<K, E> implements IGenericDAO<K, E>
61 {
62 private static final Logger LOG = LogManager.getLogger( JPAConstants.JPA_LOGGER );
63 private Class<E> _entityClass;
64 private EntityManager _defaultEM;
65
66
67
68
69 public JPAGenericDAO( )
70 {
71 _entityClass = (Class<E>) ( (ParameterizedType) getClass( ).getGenericSuperclass( ) ).getActualTypeArguments( ) [1];
72 }
73
74
75
76
77
78
79 public abstract EntityManagerFactory getEntityManagerFactory( );
80
81
82
83
84
85
86 public String getEntityClassName( )
87 {
88 return _entityClass.getName( );
89 }
90
91
92
93
94
95
96 public Class<E> getEntityClass( )
97 {
98 return _entityClass;
99 }
100
101
102
103
104
105
106 public EntityManager getEM( )
107 {
108 EntityManagerFactory emf = getEntityManagerFactory( );
109
110 if ( TransactionSynchronizationManager.isSynchronizationActive( ) )
111 {
112
113 try
114 {
115 EntityManager em = EntityManagerFactoryUtils.getTransactionalEntityManager( emf );
116
117 if ( em == null )
118 {
119 LOG.error( "getEM( ) : no EntityManager found. Will use native entity manager factory [Transaction will not be supported]" );
120 }
121 else
122 {
123 LOG.debug( "EntityManager found for the current transaction : {} - using Factory : {}", em::toString, emf::toString );
124
125 return em;
126 }
127 }
128 catch( DataAccessResourceFailureException ex )
129 {
130 LOG.error( ex );
131 }
132 }
133
134 LOG.error( "getEM( ) : no EntityManager found. Will use native entity manager factory [Transaction will not be supported]" );
135
136 if ( _defaultEM == null )
137 {
138 _defaultEM = emf.createEntityManager( );
139 }
140 return _defaultEM;
141 }
142
143
144
145
146 @Override
147 public void create( E entity )
148 {
149 LOG.debug( "Creating entity : {}", entity::toString );
150
151 EntityManager em = getEM( );
152
153 if ( em == _defaultEM )
154 {
155 em.getTransaction( ).begin( );
156 }
157 em.persist( entity );
158 if ( em == _defaultEM )
159 {
160 em.getTransaction( ).commit( );
161 }
162
163 LOG.debug( "Entity created : {}", entity::toString );
164 }
165
166
167
168
169 @Override
170 public void remove( K key )
171 {
172 EntityManager em = getEM( );
173 E entity = em.find( _entityClass, key );
174 if ( entity == null )
175 {
176 LOG.debug( "Did not find entity to remove for key {} ", key::toString );
177 return;
178 }
179 LOG.debug( "Removing entity : {}", entity::toString );
180 if ( em == _defaultEM )
181 {
182 em.getTransaction( ).begin( );
183 }
184 em.remove( entity );
185 if ( em == _defaultEM )
186 {
187 em.getTransaction( ).commit( );
188 }
189 LOG.debug( "Entity removed : {}", entity::toString );
190 }
191
192
193
194
195 @Override
196 public void update( E entity )
197 {
198 LOG.debug( "Updating entity : {}", entity::toString );
199
200 EntityManager em = getEM( );
201 if ( em == _defaultEM )
202 {
203 em.getTransaction( ).begin( );
204 }
205 em.merge( entity );
206 if ( em == _defaultEM )
207 {
208 em.getTransaction( ).commit( );
209 }
210
211 LOG.debug( "Entity Updated : {}", entity::toString );
212 }
213
214
215
216
217 @Override
218 public E findById( K key )
219 {
220 LOG.debug( "Selecting entity {} by Id ", ( ) -> getEntityClassName( ), key::toString );
221
222 return getEM( ).find( _entityClass, key );
223 }
224
225
226
227
228 @Override
229 public List<E> findAll( )
230 {
231 LOG.debug( "Selecting all entities of type : {}", ( ) -> getEntityClassName( ) );
232
233 Query query = getEM( ).createQuery( "SELECT e FROM " + getEntityClassName( ) + " e " );
234
235 return query.getResultList( );
236 }
237
238
239
240
241
242 @Override
243 public void flush( )
244 {
245 getEM( ).flush( );
246 }
247
248
249
250
251
252 @Override
253 public void detach( E entity )
254 {
255 getEM( ).detach( entity );
256 }
257 }