View Javadoc
1   package org.apache.onami.persist;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import javax.inject.Inject;
23  import javax.inject.Singleton;
24  import javax.persistence.EntityManager;
25  import javax.persistence.EntityManagerFactory;
26  import java.util.Properties;
27  
28  import static org.apache.onami.persist.Preconditions.checkNotNull;
29  
30  /**
31   * Implementation of {@link EntityManagerProvider} and {@link UnitOfWork}.
32   */
33  @Singleton
34  class EntityManagerProviderImpl
35      implements EntityManagerProvider, UnitOfWork
36  {
37  
38      /**
39       * Provider for {@link javax.persistence.EntityManagerFactory}.
40       */
41      private final EntityManagerFactoryProvider emfProvider;
42  
43      /**
44       * Additional properties to be set on every {@link EntityManager} which is created.
45       */
46      private final Properties properties;
47  
48      /**
49       * Thread local store of {@link EntityManager}s.
50       */
51      private final ThreadLocal<EntityManager> entityManagers = new ThreadLocal<EntityManager>();
52  
53      /**
54       * Constructor.
55       *
56       * @param emfProvider the provider for {@link EntityManagerFactory}. Must not be {@code null}.
57       * @param properties  additional properties to be set on every {@link EntityManager} which is created.
58       */
59      @Inject
60      public EntityManagerProviderImpl( EntityManagerFactoryProvider emfProvider,
61                                        @Nullable @ForContainerManaged Properties properties )
62      {
63          this.emfProvider = checkNotNull( emfProvider, "emfProvider is mandatory!" );
64          this.properties = properties;
65      }
66  
67      /**
68       * {@inheritDoc}
69       */
70      // @Override
71      public EntityManager get()
72          throws IllegalStateException
73      {
74          final EntityManager entityManager = entityManagers.get();
75          if ( entityManager != null )
76          {
77              return entityManager;
78          }
79          else
80          {
81              throw new IllegalStateException( "UnitOfWork is not running." );
82          }
83      }
84  
85      /**
86       * {@inheritDoc}
87       */
88      // @Override
89      public void begin()
90      {
91          if ( isActive() )
92          {
93              throw new IllegalStateException( "Unit of work has already been started." );
94          }
95          else
96          {
97              final EntityManager em = createEntityManager();
98              entityManagers.set( em );
99          }
100     }
101 
102     /**
103      * @return a new entity manager instance.
104      */
105     private EntityManager createEntityManager()
106     {
107         final EntityManagerFactory emf = emfProvider.get();
108         if ( null == properties )
109         {
110             return emf.createEntityManager();
111         }
112         else
113         {
114             return emf.createEntityManager( properties );
115         }
116     }
117 
118     /**
119      * {@inheritDoc}
120      */
121     // @Override
122     public boolean isActive()
123     {
124         return entityManagers.get() != null;
125     }
126 
127     /**
128      * {@inheritDoc}
129      */
130     // @Override
131     public void end()
132     {
133         final EntityManager em = entityManagers.get();
134         if ( em != null )
135         {
136             closeAndRemoveEntityManager( em );
137         }
138     }
139 
140     /**
141      * closes the entity manager and removes it from the internal storage.
142      *
143      * @param em the entity manager to close
144      */
145     private void closeAndRemoveEntityManager( EntityManager em )
146     {
147         try
148         {
149             em.close();
150         }
151         finally
152         {
153             entityManagers.remove();
154         }
155     }
156 
157 }