001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. 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 distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.examples.rest.petstore; 014 015import java.util.*; 016 017import javax.persistence.*; 018 019import org.apache.juneau.utils.*; 020 021/** 022 * Superclass for DAOs that use the JPA entity manager. 023 * 024 * <ul class='seealso'> 025 * <li class='extlink'>{@source} 026 * </ul> 027 */ 028public class AbstractPersistenceService { 029 030 private final EntityManagerFactory entityManagerFactory; 031 032 /** 033 * Constructor. 034 */ 035 public AbstractPersistenceService() { 036 entityManagerFactory = Persistence.createEntityManagerFactory("test"); 037 } 038 039 /** 040 * Retrieves an entity manager session. 041 * 042 * @return The entity manager session. 043 */ 044 protected EntityManager getEntityManager() { 045 return entityManagerFactory.createEntityManager(); 046 } 047 048 /** 049 * Retrieves the specified JPA bean from the repository. 050 * 051 * @param em The entity manager to use to retrieve the bean. 052 * @param t The bean type to retrieve. 053 * @param id The primary key value. 054 * @return The JPA bean, or null if not found. 055 */ 056 protected <T> T find(EntityManager em, Class<T> t, Object id) { 057 return em.find(t, id); 058 } 059 060 /** 061 * Same as {@link #find(EntityManager, Class, Object)} but uses a new entity manager. 062 * 063 * @param t The bean type to retrieve. 064 * @param id The primary key value. 065 * @return The JPA bean, or null if not found. 066 */ 067 protected <T> T find(Class<T> t, Object id) { 068 return find(getEntityManager(), t, id); 069 } 070 071 /** 072 * Store the specified JPA bean in the repository. 073 * 074 * @param em The entity manager to use to store and merge the bean. 075 * @param t The bean to store. 076 * @return The merged JPA bean returned by the {@link EntityManager#merge(Object)} method, or null if the bean was null. 077 */ 078 protected <T> T merge(EntityManager em, T t) { 079 if (t == null) 080 return null; 081 try { 082 EntityTransaction et = em.getTransaction(); 083 et.begin(); 084 t = em.merge(t); 085 et.commit(); 086 return t; 087 } finally { 088 em.close(); 089 } 090 } 091 092 /** 093 * Same as {@link #merge(EntityManager, Object)} but uses a new entity manager. 094 * 095 * @param t The bean to store. 096 * @return The merged JPA bean returned by the {@link EntityManager#merge(Object)} method, or null if the bean was null. 097 */ 098 protected <T> T merge(T t) { 099 return merge(getEntityManager(), t); 100 } 101 102 /** 103 * Store the specified JPA beans in the repository. 104 * 105 * All values are persisted in the same transaction. 106 * 107 * @param em The entity manager to use to store and merge the beans. 108 * @param c The collection of beans to store. 109 * @return The merged JPA beans returned by the {@link EntityManager#merge(Object)} method. 110 */ 111 protected <T> Collection<T> merge(EntityManager em, Collection<T> c) { 112 Collection<T> c2 = new ArrayList<>(); 113 try { 114 EntityTransaction et = em.getTransaction(); 115 et.begin(); 116 for (T t : c) 117 c2.add(em.merge(t)); 118 et.commit(); 119 return c2; 120 } finally { 121 em.close(); 122 } 123 } 124 125 /** 126 * Same as {@link #merge(EntityManager, Collection)} but uses a new entity manager. 127 * 128 * @param c The collection of beans to store. 129 * @return The merged JPA beans returned by the {@link EntityManager#merge(Object)} method. 130 */ 131 protected <T> Collection<T> merge(Collection<T> c) { 132 return merge(getEntityManager(), c); 133 } 134 135 /** 136 * Remove the specified JPA bean from the repository. 137 * 138 * @param t The bean type to remove. 139 * @param id The primary key value. 140 */ 141 protected <T> void remove(Class<T> t, Object id) { 142 EntityManager em = getEntityManager(); 143 remove(em, find(em, t, id)); 144 } 145 146 /** 147 * Remove the specified JPA bean from the repository. 148 * 149 * @param em The entity manager used to retrieve the bean. 150 * @param t The bean to remove. Can be null. 151 */ 152 protected <T> void remove(EntityManager em, T t) { 153 if (t == null) 154 return; 155 try { 156 EntityTransaction et = em.getTransaction(); 157 et.begin(); 158 em.remove(t); 159 et.commit(); 160 } finally { 161 em.close(); 162 } 163 } 164 165 /** 166 * Runs a JPA query and returns the results. 167 * 168 * @param <T> The bean type. 169 * @param em The entity manager to use to retrieve the beans. 170 * @param query The JPA query. 171 * @param t The bean type. 172 * @param searchArgs Optional search arguments. 173 * @return The results. 174 */ 175 protected <T> List<T> query(EntityManager em, String query, Class<T> t, SearchArgs searchArgs) { 176 TypedQuery<T> q = em.createQuery(query, t); 177 if (searchArgs != null) { 178 q.setMaxResults(searchArgs.getLimit() == 0 ? 100 : searchArgs.getLimit()); 179 q.setFirstResult(searchArgs.getPosition()); 180 } 181 return em.createQuery(query, t).getResultList(); 182 } 183 184 /** 185 * Same as {@link #query(EntityManager,String,Class,SearchArgs)} but uses a new entity manager. 186 * 187 * @param <T> The bean type. 188 * @param query The JPA query. 189 * @param t The bean type. 190 * @param searchArgs Optional search arguments. 191 * @return The results. 192 */ 193 protected <T> List<T> query(String query, Class<T> t, SearchArgs searchArgs) { 194 return query(getEntityManager(), query, t, searchArgs); 195 } 196 197 /** 198 * Runs a JPA parameterized query and returns the results. 199 * 200 * @param em The entity manager to use to retrieve the beans. 201 * @param query The JPA query. 202 * @param t The bean type. 203 * @param params The query parameter values. 204 * @return The results. 205 */ 206 protected <T> List<T> query(EntityManager em, String query, Class<T> t, Map<String,Object> params) { 207 TypedQuery<T> tq = em.createQuery(query, t); 208 for (Map.Entry<String,Object> e : params.entrySet()) { 209 tq.setParameter(e.getKey(), e.getValue()); 210 } 211 return tq.getResultList(); 212 } 213 214 /** 215 * Same as {@link #query(EntityManager,String,Class,Map)} but uses a new entity manager. 216 * 217 * @param query The JPA query. 218 * @param t The bean type. 219 * @param params The query parameter values. 220 * @return The results. 221 */ 222 protected <T> List<T> query(String query, Class<T> t, Map<String,Object> params) { 223 return query(getEntityManager(), query, t, params); 224 } 225 226 /** 227 * Runs a JPA update statement. 228 * 229 * @param em The entity manager to use to run the statement. 230 * @param query The JPA update statement. 231 * @return The number of rows modified. 232 */ 233 protected int update(EntityManager em, String query) { 234 return em.createQuery(query).executeUpdate(); 235 } 236 237 /** 238 * Same as {@link #update(EntityManager,String)} but uses a new entity manager. 239 * 240 * @param query The JPA update statement. 241 * @return The number of rows modified. 242 */ 243 protected int update(String query) { 244 return update(getEntityManager(), query); 245 } 246 247 /** 248 * Runs a JPA parameterized update statement. 249 * 250 * @param em The entity manager to use to run the statement. 251 * @param query The JPA update statement. 252 * @param params The query parameter values. 253 * @return The number of rows modified. 254 */ 255 protected int update(EntityManager em, String query, Map<String,Object> params) { 256 Query q = em.createQuery(query); 257 for (Map.Entry<String,Object> e : params.entrySet()) { 258 q.setParameter(e.getKey(), e.getValue()); 259 } 260 return q.executeUpdate(); 261 } 262 263 /** 264 * Same as {@link #update(EntityManager,String,Map)} but uses a new entity manager. 265 * 266 * @param query The JPA update statement. 267 * @param params The query parameter values. 268 * @return The number of rows modified. 269 */ 270 protected int update(String query, Map<String,Object> params) { 271 return update(getEntityManager(), query, params); 272 } 273}