package de.cinovo.cloudconductor.server.dao.hibernate; import java.util.List; import javax.persistence.EntityNotFoundException; import javax.persistence.TypedQuery; import org.springframework.transaction.annotation.Transactional; import de.cinovo.cloudconductor.server.model.IVersionized; /** * Copyright 2014 Cinovo AG<br> * <br> * * @author psigloch * * @param <E> the entity */ public abstract class AVersionedEntityHib<E extends IVersionized<Long>> extends AAuditedEntityHib<E, Long> { @Override @Transactional public E save(final E element, String auditMessage) { if ((element.getId() == null) || (element.getId() < 0)) { return this.saveNewElement(element); } if (auditMessage == null) { return super.save(this.createNewRevision(element), this.getChangeEntry(element)); } return super.save(this.createNewRevision(element), auditMessage); } @Override @Transactional public E save(E element) { this.entityManager.detach(element); return this.save(element, null); } @SuppressWarnings("unchecked") @Transactional private E createNewRevision(E element) { E r = (E) element.cloneNew(); if ((r.getVersion() == null) || (r.getVersion() < 0)) { r.setVersion(0L); } else { r.setVersion(element.getVersion() + 1); } r.setDeleted(false); r.setOrigId(element.getOrigId()); return r; } @Transactional private E saveNewElement(E element) { element.setVersion(0L); element.setDeleted(false); E ele = super.save(element); ele.setOrigId(ele.getId()); return this.entityManager.merge(ele); } @Override @Transactional public void delete(final E element, String auditMessage) { element.setDeleted(true); super.save(element, auditMessage); } @Override @Transactional public void delete(final E element) { element.setDeleted(true); super.save(element); } @Override @Transactional public void deleteById(final Long id) { final E element = this.findById(id); if (element == null) { throw new EntityNotFoundException(); } this.delete(element); } @Transactional protected List<E> findVersionedList() { final TypedQuery<E> query = this.entityManager.createQuery(this.getFindAllListQuery(), this.getEntityClass()); return query.getResultList(); } @Transactional protected final E findVersionedByQuery(final String query, String as, final Object... params) { return super.findByQuery(this.getVersionizedQuerry(query, as), params); } @Transactional protected final List<E> findVersionedListByQuery(final String query, String as, final Object... params) { return super.findListByQuery(this.getVersionizedQuerry(query, as), params); } @Transactional protected String getVersionizedQuerry(String query, String as) { String maxVersion = "SELECT MAX(second.version) FROM " + this.getEntityClass().getSimpleName() + " as second WHERE second.origId = " + as + ".origId"; StringBuilder newQuery = new StringBuilder(); newQuery.append(query); if (query.contains("WHERE")) { newQuery.append(" AND "); } else { newQuery.append(" as " + as + " WHERE "); } newQuery.append(as); newQuery.append(".deleted=false AND "); newQuery.append(as); newQuery.append(".version=("); newQuery.append(maxVersion); newQuery.append(")"); return newQuery.toString(); } @Override @Transactional protected String getFindListQuery() { return this.getVersionizedQuerry("FROM " + this.getEntityClass().getSimpleName(), "first"); } @Transactional protected String getFindAllListQuery() { return "FROM " + this.getEntityClass().getSimpleName(); } }