View Javadoc
1   /*
2    * Copyright (c) 2002-2014, Mairie de Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.util.jpa;
35  
36  import org.apache.log4j.Logger;
37  
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   * Class JPAGenericDAO
55   * @param <K> Type of the entity's key
56   * @param <E> Type of the entity
57   */
58  public abstract class JPAGenericDAO<K, E> implements IGenericDAO<K, E>
59  {
60      private static final Logger _log = Logger.getLogger( JPAConstants.JPA_LOGGER );
61      private Class<E> _entityClass;
62  
63      /**
64       * Constructor
65       */
66      @SuppressWarnings( "unchecked" )
67      public JPAGenericDAO(  )
68      {
69          _entityClass = (Class<E>) ( (ParameterizedType) getClass(  ).getGenericSuperclass(  ) ).getActualTypeArguments(  )[1];
70      }
71  
72      /**
73       * Inherit classes should provide their Entity Manager Factory
74       * @return The Entity Manager Factory that will create Entity Manager for this DAO
75       */
76      public abstract EntityManagerFactory getEntityManagerFactory(  );
77  
78      /**
79       * Returns the entity class name
80       * @return The entity class name
81       */
82      public String getEntityClassName(  )
83      {
84          return _entityClass.getName(  );
85      }
86  
87      /**
88       * Gets the entity class
89       * @return the entity class
90       */
91      public Class<E> getEntityClass(  )
92      {
93          return _entityClass;
94      }
95  
96      /**
97       * Return the Entity Manager
98       * @return The Entity Manager
99       */
100     public EntityManager getEM(  )
101     {
102         EntityManagerFactory emf = getEntityManagerFactory(  );
103 
104         if ( TransactionSynchronizationManager.isSynchronizationActive(  ) )
105         {
106             // first, get Spring entitymanager (if available)
107             try
108             {
109                 EntityManager em = EntityManagerFactoryUtils.getTransactionalEntityManager( emf );
110 
111                 if ( em == null )
112                 {
113                     _log.error( 
114                         "getEM(  ) : no EntityManager found. Will use native entity manager factory [Transaction will not be supported]" );
115                 }
116                 else
117                 {
118                     _log.debug( "EntityManager found for the current transaction : " + em.toString(  ) +
119                         " - using Factory : " + emf.toString(  ) );
120 
121                     return em;
122                 }
123             }
124             catch ( DataAccessResourceFailureException ex )
125             {
126                 _log.error( ex );
127             }
128         }
129 
130         _log.error( 
131             "getEM(  ) : no EntityManager found. Will use native entity manager factory [Transaction will not be supported]" );
132 
133         return emf.createEntityManager(  );
134     }
135 
136     /**
137      * {@inheritDoc }
138      */
139     public void create( E entity )
140     {
141         _log.debug( "Creating entity : " + entity.toString(  ) );
142 
143         EntityManager em = getEM(  );
144         em.persist( entity );
145         _log.debug( "Entity created : " + entity.toString(  ) );
146     }
147 
148     /**
149      * {@inheritDoc }
150      */
151     public void remove( K key )
152     {
153         EntityManager em = getEM(  );
154         E entity = em.find( _entityClass, key );
155         _log.debug( "Removing entity : " + entity.toString(  ) );
156         em.remove( entity );
157         _log.debug( "Entity removed : " + entity.toString(  ) );
158     }
159 
160     /**
161      * {@inheritDoc }
162      */
163     public void update( E entity )
164     {
165         _log.debug( "Updating entity : " + entity.toString(  ) );
166 
167         EntityManager em = getEM(  );
168         em.merge( entity );
169         _log.debug( "Entity Updated : " + entity.toString(  ) );
170     }
171 
172     /**
173      * {@inheritDoc }
174      */
175     public E findById( K key )
176     {
177         _log.debug( "Selecting entity " + getEntityClassName(  ) + " by ID : " + key.toString(  ) );
178 
179         return (E) getEM(  ).find( _entityClass, key );
180     }
181 
182     /**
183      * {@inheritDoc }
184      */
185     public List<E> findAll(  )
186     {
187         _log.debug( "Selecting all entities of type : " + getEntityClassName(  ) );
188 
189         Query query = getEM(  ).createQuery( "SELECT e FROM " + getEntityClassName(  ) + " e " );
190 
191         return query.getResultList(  );
192     }
193 
194     /**
195      *
196      *{@inheritDoc}
197      */
198     public void flush(  )
199     {
200         getEM(  ).flush(  );
201     }
202 
203     /**
204      *
205      *{@inheritDoc}
206      */
207     public void detach( E entity )
208     {
209         getEM(  ).detach( entity );
210     }
211 }