/**
* 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());
}
}