/*******************************************************************************
* Copyright (c) 2012-2017 Codenvy, S.A.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.commons.test.tck.repository;
import com.google.inject.Inject;
import com.google.inject.persist.UnitOfWork;
import javax.inject.Provider;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import java.util.Collection;
import static java.lang.String.format;
/**
* Simplifies implementation for Jpa repository in general case.
*
* Expected usage:
* <pre>
* class MyTckModule extends TckModule {
* @Override configure() {
* bind(new TypeLiteral<TckRepository<UserImpl>>() {})
* .toInstance(new JpaTckRepository(Concrete.class));
* }
* }
* </pre>
*
* @param <T>
* type of the entity
* @author Yevhenii Voevodin
*/
public class JpaTckRepository<T> implements TckRepository<T> {
@Inject
protected Provider<EntityManager> managerProvider;
@Inject
protected UnitOfWork uow;
private final Class<? extends T> entityClass;
public JpaTckRepository(Class<? extends T> entityClass) {
this.entityClass = entityClass;
}
@Override
public void createAll(Collection<? extends T> entities) throws TckRepositoryException {
uow.begin();
final EntityManager manager = managerProvider.get();
try {
manager.getTransaction().begin();
for (T entity : entities) {
manager.persist(entity);
manager.flush();
}
manager.getTransaction().commit();
} catch (RuntimeException x) {
if (manager.getTransaction().isActive()) {
manager.getTransaction().rollback();
}
throw new TckRepositoryException(x.getLocalizedMessage(), x);
} finally {
uow.end();
}
}
@Override
public void removeAll() throws TckRepositoryException {
uow.begin();
final EntityManager manager = managerProvider.get();
try {
manager.getTransaction().begin();
// The query 'DELETE FROM Entity' won't be correct as it will ignore orphanRemoval
// and may also ignore some configuration options, while EntityManager#remove won't
manager.createQuery(format("SELECT e FROM %s e", getEntityName(entityClass)), entityClass)
.getResultList()
.forEach(manager::remove);
manager.getTransaction().commit();
} catch (RuntimeException x) {
if (manager.getTransaction().isActive()) {
manager.getTransaction().rollback();
}
throw new TckRepositoryException(x.getLocalizedMessage(), x);
} finally {
uow.end();
}
}
private String getEntityName(Class<?> clazz) {
if (!clazz.isAnnotationPresent(Entity.class)) {
return clazz.getSimpleName();
}
final Entity entity = clazz.getAnnotation(Entity.class);
if (entity.name().isEmpty()) {
return clazz.getSimpleName();
}
return entity.name();
}
}