/** * Copyright 2010 CosmoCode GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.cosmocode.palava.entity; import javax.management.Query; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; import de.cosmocode.collections.Procedure; import de.cosmocode.palava.jpa.Transactional; import de.cosmocode.palava.model.base.Copyable; /** * Abstract base implementation of the {@link EntityService} interface. * * <p> * <strong>Note</strong>: This implementation does not provide a meaningful * {@link EntityService#delete(Object)} method. Decisions about deleting * or hiding entites are left to sub-classes. Create and update are marked * with @Transactional to use or create transactions for database actions. * </p> * * @author Willi Schoenborn * @param <T> generic entity type */ public abstract class AbstractEntityService<T> extends AbstractReadOnlyEntityService<T> implements EntityService<T> { private static final Logger LOG = LoggerFactory.getLogger(AbstractEntityService.class); @Transactional @Override public T create(T entity) { LOG.debug("Creating {} in database", entity); entityManager().persist(entity); return entity; } @Transactional @Override public T update(T entity) { LOG.debug("Updating {}", entity); return entityManager().merge(entity); } @Transactional @Override public void each(Procedure<? super T> procedure) { each(getTypedQuery(), procedure); } @Override public void each(String queryName, Procedure<? super T> procedure) { each(prepare(queryName), procedure); } @Transactional @Override public void each(TypedQuery<T> query, Procedure<? super T> procedure) { Preconditions.checkNotNull(procedure, "Procedure"); for (T entity : list(query)) { LOG.trace("Applying {} to {}", procedure, entity); procedure.apply(entity); } } @Transactional @Override public void each(Procedure<? super T> procedure, int batchSize) { each(getTypedQuery(), procedure, batchSize); } @Override public void each(String queryName, Procedure<? super T> procedure, int batchSize) { each(prepare(queryName), procedure, batchSize); } @Transactional @Override public void each(TypedQuery<T> query, Procedure<? super T> procedure, int batchSize) { each(query, procedure, batchSize, Batch.NOOP); } @Transactional @Override public void each(Procedure<? super T> procedure, int batchSize, Procedure<? super EntityManager> batchProcedure) { each(getTypedQuery(), procedure, batchSize, batchProcedure); } @Override public void each(String queryName, Procedure<? super T> procedure, int batchSize, Procedure<? super EntityManager> batchProcedure) { each(prepare(queryName), procedure, batchSize, batchProcedure); } @Transactional @Override public void each(TypedQuery<T> query, Procedure<? super T> procedure, int batchSize, Procedure<? super EntityManager> batchProcedure) { Preconditions.checkNotNull(procedure, "Procedure"); Preconditions.checkNotNull(batchProcedure, "BatchProcedure"); int i = 1; for (T entity : iterate(query, batchSize)) { LOG.trace("Applying {} to {}", procedure, entity); procedure.apply(entity); if (i++ % batchSize == 0) { batchProcedure.apply(entityManager()); } } } @Transactional @Override public <C extends Copyable<T>> T createCopy(C entity) { LOG.debug("Copying {}", entity); return create(entity.copy()); } }