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 */ 024public class AbstractPersistenceService { 025 026 private final EntityManagerFactory entityManagerFactory; 027 028 public AbstractPersistenceService() { 029 entityManagerFactory = Persistence.createEntityManagerFactory("test"); 030 } 031 032 /** 033 * Retrieves an entity manager session. 034 */ 035 protected EntityManager getEntityManager() { 036 return entityManagerFactory.createEntityManager(); 037 } 038 039 /** 040 * Retrieves the specified JPA bean from the repository. 041 * 042 * @param em The entity manager to use to retrieve the bean. 043 * @param t The bean type to retrieve. 044 * @param id The primary key value. 045 * @return The JPA bean, or null if not found. 046 */ 047 protected <T> T find(EntityManager em, Class<T> t, Object id) { 048 return em.find(t, id); 049 } 050 051 /** 052 * Same as {@link #find(EntityManager, Class, Object)} but uses a new entity manager. 053 * 054 * @param t The bean type to retrieve. 055 * @param id The primary key value. 056 * @return The JPA bean, or null if not found. 057 */ 058 protected <T> T find(Class<T> t, Object id) { 059 return find(getEntityManager(), t, id); 060 } 061 062 /** 063 * Store the specified JPA bean in the repository. 064 * 065 * @param em The entity manager to use to store and merge the bean. 066 * @param t The bean to store. 067 * @return The merged JPA bean returned by the {@link EntityManager#merge(Object)} method, or null if the bean was null. 068 */ 069 protected <T> T merge(EntityManager em, T t) { 070 if (t == null) 071 return null; 072 try { 073 EntityTransaction et = em.getTransaction(); 074 et.begin(); 075 t = em.merge(t); 076 et.commit(); 077 return t; 078 } finally { 079 em.close(); 080 } 081 } 082 083 /** 084 * Same as {@link #merge(EntityManager, Object)} but uses a new entity manager. 085 * 086 * @param t The bean to store. 087 * @return The merged JPA bean returned by the {@link EntityManager#merge(Object)} method, or null if the bean was null. 088 */ 089 protected <T> T merge(T t) { 090 return merge(getEntityManager(), t); 091 } 092 093 /** 094 * Store the specified JPA beans in the repository. 095 * 096 * All values are persisted in the same transaction. 097 * 098 * @param em The entity manager to use to store and merge the beans. 099 * @param c The collection of beans to store. 100 * @return The merged JPA beans returned by the {@link EntityManager#merge(Object)} method. 101 */ 102 protected <T> Collection<T> merge(EntityManager em, Collection<T> c) { 103 Collection<T> c2 = new ArrayList<>(); 104 try { 105 EntityTransaction et = em.getTransaction(); 106 et.begin(); 107 for (T t : c) 108 c2.add(em.merge(t)); 109 et.commit(); 110 return c2; 111 } finally { 112 em.close(); 113 } 114 } 115 116 /** 117 * Same as {@link #merge(EntityManager, Collection)} but uses a new entity manager. 118 * 119 * @param c The collection of beans to store. 120 * @return The merged JPA beans returned by the {@link EntityManager#merge(Object)} method. 121 */ 122 protected <T> Collection<T> merge(Collection<T> c) { 123 return merge(getEntityManager(), c); 124 } 125 126 /** 127 * Remove the specified JPA bean from the repository. 128 * 129 * @param t The bean type to remove. 130 * @param id The primary key value. 131 */ 132 protected <T> void remove(Class<T> t, Object id) { 133 EntityManager em = getEntityManager(); 134 remove(em, find(em, t, id)); 135 } 136 137 /** 138 * Remove the specified JPA bean from the repository. 139 * 140 * @param em The entity manager used to retrieve the bean. 141 * @param t The bean to remove. Can be null. 142 */ 143 protected <T> void remove(EntityManager em, T t) { 144 if (t == null) 145 return; 146 try { 147 EntityTransaction et = em.getTransaction(); 148 et.begin(); 149 em.remove(t); 150 et.commit(); 151 } finally { 152 em.close(); 153 } 154 } 155 156 /** 157 * Runs a JPA query and returns the results. 158 * 159 * @param em The entity manager to use to retrieve the beans. 160 * @param query The JPA query. 161 * @param t The bean type. 162 */ 163 protected <T> List<T> query(EntityManager em, String query, Class<T> t, SearchArgs searchArgs) { 164 TypedQuery<T> q = em.createQuery(query, t); 165 if (searchArgs != null) { 166 q.setMaxResults(searchArgs.getLimit() == 0 ? 100 : searchArgs.getLimit()); 167 q.setFirstResult(searchArgs.getPosition()); 168 } 169 return em.createQuery(query, t).getResultList(); 170 } 171 172 /** 173 * Same as {@link #query(EntityManager,String,Class,SearchArgs)} but uses a new entity manager. 174 * 175 * @param query The JPA query. 176 * @param t The bean type. 177 */ 178 protected <T> List<T> query(String query, Class<T> t, SearchArgs searchArgs) { 179 return query(getEntityManager(), query, t, searchArgs); 180 } 181 182 /** 183 * Runs a JPA parameterized query and returns the results. 184 * 185 * @param em The entity manager to use to retrieve the beans. 186 * @param query The JPA query. 187 * @param t The bean type. 188 * @param params The query parameter values. 189 */ 190 protected <T> List<T> query(EntityManager em, String query, Class<T> t, Map<String,Object> params) { 191 TypedQuery<T> tq = em.createQuery(query, t); 192 for (Map.Entry<String,Object> e : params.entrySet()) { 193 tq.setParameter(e.getKey(), e.getValue()); 194 } 195 return tq.getResultList(); 196 } 197 198 /** 199 * Same as {@link #query(EntityManager,String,Class,Map)} but uses a new entity manager. 200 * 201 * @param query The JPA query. 202 * @param t The bean type. 203 * @param params The query parameter values. 204 */ 205 protected <T> List<T> query(String query, Class<T> t, Map<String,Object> params) { 206 return query(getEntityManager(), query, t, params); 207 } 208 209 /** 210 * Runs a JPA update statement. 211 * 212 * @param em The entity manager to use to run the statement. 213 * @param query The JPA update statement. 214 * @return The number of rows modified. 215 */ 216 protected int update(EntityManager em, String query) { 217 return em.createQuery(query).executeUpdate(); 218 } 219 220 /** 221 * Same as {@link #update(EntityManager,String)} but uses a new entity manager. 222 * 223 * @param query The JPA update statement. 224 * @return The number of rows modified. 225 */ 226 protected int update(String query) { 227 return update(getEntityManager(), query); 228 } 229 230 /** 231 * Runs a JPA parameterized update statement. 232 * 233 * @param em The entity manager to use to run the statement. 234 * @param query The JPA update statement. 235 * @param params The query parameter values. 236 * @return The number of rows modified. 237 */ 238 protected int update(EntityManager em, String query, Map<String,Object> params) { 239 Query q = em.createQuery(query); 240 for (Map.Entry<String,Object> e : params.entrySet()) { 241 q.setParameter(e.getKey(), e.getValue()); 242 } 243 return q.executeUpdate(); 244 } 245 246 /** 247 * Same as {@link #update(EntityManager,String,Map)} but uses a new entity manager. 248 * 249 * @param query The JPA update statement. 250 * @param params The query parameter values. 251 * @return The number of rows modified. 252 */ 253 protected int update(String query, Map<String,Object> params) { 254 return update(getEntityManager(), query, params); 255 } 256}