package com.ikokoon.serenity.persistence; import java.util.List; import java.util.Map; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContextType; import org.apache.log4j.Logger; import com.ikokoon.serenity.IConstants; import com.ikokoon.serenity.model.Composite; import com.ikokoon.toolkit.Toolkit; /** * This is the JPA database implementation. This class could be used in the future if so desired by a user of the Serenity plugin. The issue with the * JPA database is the speed of persistence and where the database will be. This could be configurable of course, but then the user has to do some * serious configuration which will require technical knowledge, and of course set up a database. Too much effort I thinks. * * @author Michael Couck * @since 20.12.09 * @version 01.00 */ public class DataBaseJpa extends DataBase { private Logger logger = Logger.getLogger(this.getClass()); @PersistenceContext(type = PersistenceContextType.TRANSACTION, unitName = IConstants.SERENITY_PERSISTENCE_UNIT) private EntityManager entityManager; private boolean closed = true; /** * Constructor opens the entity manager. */ DataBaseJpa() { getEntityManager(); closed = false; } /** * {@inheritDoc} */ public synchronized <E extends Composite<?, ?>> E find(Class<E> klass, Long id) { boolean commit = begin(); try { E e = entityManager.find(klass, id); logger.info("find(klass, id) : " + e); return e; } catch (Exception e) { logger.error("Exception finding : " + klass + ", " + id, e); } finally { commit(commit); } return null; } public synchronized <E extends Composite<?, ?>> E find(Class<E> klass, List<?> parameters) { Long id = Toolkit.hash(parameters.toArray()); return find(klass, id); } /** * {@inheritDoc} */ @SuppressWarnings("unchecked") public synchronized <E extends Composite<?, ?>> List<E> find(Class<E> klass) { return entityManager.createQuery("from " + klass.getSimpleName()).getResultList(); } /** * {@inheritDoc} */ public <E extends Composite<?, ?>> List<E> find(Class<E> klass, Map<String, ?> parameters) { throw new RuntimeException("Not implempented."); } /** * {@inheritDoc} */ public synchronized boolean isClosed() { return closed; } /** * {@inheritDoc} */ public synchronized <E extends Composite<?, ?>> E persist(E composite) { // setId(composite); boolean commit = begin(); entityManager.persist(composite); // entityManager.refresh(composite); commit(commit); return composite; } /** * {@inheritDoc} */ public synchronized <E extends Composite<?, ?>> E remove(Class<E> klass, Long id) { E composite = find(klass, id); if (composite != null) { boolean commit = begin(); entityManager.remove(composite); commit(commit); } return composite; } /** * {@inheritDoc} */ public synchronized void close() { logger.info("Closing the JPA database : " + entityManager.isOpen()); if (entityManager.isOpen()) { boolean commit = begin(); try { entityManager.flush(); } finally { commit(commit); } entityManager.close(); closed = true; } } /** * This method starts a transaction for the entity manager. */ private synchronized boolean begin() { EntityTransaction transaction = entityManager.getTransaction(); if (!transaction.isActive()) { entityManager.getTransaction().begin(); return true; } return false; } /** * This method commits the transaction for he entity manager. */ private synchronized void commit(boolean commit) { if (commit) { EntityTransaction transaction = entityManager.getTransaction(); if (transaction.isActive()) { if (!transaction.getRollbackOnly()) { transaction.commit(); } else { transaction.rollback(); } } } } /** * Initialises the entity manager. */ private synchronized EntityManager getEntityManager() { if (entityManager == null) { try { EntityManagerFactory factory = Persistence.createEntityManagerFactory(IConstants.SERENITY_PERSISTENCE_UNIT); entityManager = factory.createEntityManager(); } catch (Exception e) { logger.error("Error setting up the entity manager in stand alone.", e); } } return entityManager; } public <E extends Composite<?, ?>> List<E> find(Class<E> klass, int start, int end) { return null; } }