ItEr13S05ArquitecturaServidorItEr12S05: worker-edition Experiment to improve conversation support for edition of

workers.

Experiment to improve conversation support for edition of workers. Unfortunately, it does not work correctly.
This commit is contained in:
Fernando Bellas Permuy 2009-06-17 19:30:08 +02:00 committed by Javier Moran Rua
parent 50507413c2
commit e6de5b351e
9 changed files with 124 additions and 34 deletions

View file

@ -18,10 +18,34 @@ import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
public interface IGenericDao <E, PK extends Serializable>{
/**
* It updates and inserts the object passed as a parameter.
* It updates or inserts the instance passed as a parameter. If the
* instance passed as parameter already exists in the database, the
* instance is reattached to the underlying ORM session. In this case, if
* the version field is older than the one in the database,
* <code>org.springframework.dao.OptimisticLockingFailureException</code>
* is thrown.
*/
public void save(E entity);
/**
* It reattaches the instance passed as a parameter to the underlying ORM
* session. It can only be used in READ-ONLY transactions. If the
* version field is older than the one in the database,
* <code>org.springframework.dao.OptimisticLockingFailureException</code>
* is thrown.
*/
public void reattachForRead(E entity);
/**
* It sets a WRITE lock on the instance passed as a parameter. The instance
* must exist in the database. Other concurrent transactions will be
* blocked if they try to write (but can read) on the same persistent
* instance. If the version field is older than the one in the database,
* <code>org.springframework.dao.OptimisticLockingFailureException</code>
* is thrown. The lock is released when the transaction finishes.
*/
public void lock(E entity);
public E find(PK id) throws InstanceNotFoundException;
public boolean exists(PK id);

View file

@ -6,6 +6,7 @@ import java.util.List;
import org.apache.commons.lang.Validate;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections;
@ -74,6 +75,26 @@ public class GenericDaoHibernate<E, PK extends Serializable> implements
}
public void reattachForRead(E entity) {
try {
getSession().lock(entity, LockMode.READ);
} catch (HibernateException e) {
throw convertHibernateAccessException(e);
}
}
public void lock(E entity) {
try {
getSession().lock(entity, LockMode.UPGRADE);
} catch (HibernateException e) {
throw convertHibernateAccessException(e);
}
}
@SuppressWarnings("unchecked")
public E find(PK id) throws InstanceNotFoundException {

View file

@ -4,6 +4,7 @@ import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections;
@ -59,6 +60,14 @@ public class GenericDaoHibernateTemplate<E, PK extends Serializable> implements
hibernateTemplate.saveOrUpdate(entity);
}
public void reattachForRead(E entity) {
hibernateTemplate.lock(entity, LockMode.READ);
}
public void lock(E entity) {
hibernateTemplate.lock(entity, LockMode.UPGRADE);
}
@SuppressWarnings("unchecked")
public E find(PK id) throws InstanceNotFoundException {

View file

@ -23,6 +23,14 @@ public interface ResourceService {
*/
public void saveResource(Resource resource);
/**
* It checks if the version of the detached object passed as a parameter is
* older than the one in the database. If it is older, it throws
* <code>org.springframework.dao.OptimisticLockingFailureException</code>.
* It can not be called as part of a READ-WRITE transaction.
*/
public void checkVersion(Resource resource);
public Resource findResource(Long resourceId)
throws InstanceNotFoundException;

View file

@ -35,6 +35,11 @@ public class ResourceServiceImpl implements ResourceService {
resourceDao.save(resource);
}
@Transactional(readOnly = true)
public void checkVersion(Resource resource) {
resourceDao.reattachForRead(resource);
}
private void checkResourceIsOk(Resource resource) {
List<ICriterionType<?>> types = criterionsBootstrap.getTypes();
resource.checkNotOverlaps(types);

View file

@ -3,7 +3,6 @@ package org.navalplanner.web.resources.worker;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.entities.Criterion;
@ -31,14 +30,9 @@ public interface IWorkerModel {
boolean isCreating();
Set<CriterionSatisfaction> getCriterionSatisfactions(Worker worker);
Worker findResource(long workerId);
Map<ICriterionType<?>, Collection<Criterion>> getLaboralRelatedCriterions();
List<CriterionSatisfaction> getLaboralRelatedCriterionSatisfactions(
Worker worker);
List<CriterionSatisfaction> getLaboralRelatedCriterionSatisfactions();
public enum AddingSatisfactionResult {
OK, SATISFACTION_WRONG, DONT_COMPLY_OVERLAPPING_RESTRICTIONS;
@ -48,4 +42,11 @@ public interface IWorkerModel {
CriterionSatisfaction originalSatisfaction,
CriterionSatisfaction edited);
void removeSatisfaction(CriterionSatisfaction satisfaction);
public void assignCriteria(Collection<? extends Criterion> criteria);
void unassignSatisfactions(
Collection<? extends CriterionSatisfaction> satisfactions);
}

View file

@ -71,7 +71,7 @@ public class LocalizationsController extends GenericForwardComposer {
@Override
public void onEvent(Event event) throws Exception {
workerModel.getLocalizationsAssigner().unassign(
workerModel.unassignSatisfactions(
extractValuesOf(activeSatisfactions.getSelectedItems(),
CriterionSatisfaction.class));
reloadLists();
@ -84,7 +84,7 @@ public class LocalizationsController extends GenericForwardComposer {
public void onEvent(Event event) throws Exception {
Set<Listitem> selectedItems = criterionsNotAssigned
.getSelectedItems();
workerModel.getLocalizationsAssigner().assign(
workerModel.assignCriteria(
extractValuesOf(selectedItems, Criterion.class));
reloadLists();
}

View file

@ -77,14 +77,13 @@ public class WorkRelationshipsController extends GenericForwardComposer {
return new ArrayList<CriterionSatisfaction>();
} else {
return workerModel
.getLaboralRelatedCriterionSatisfactions(getWorker());
.getLaboralRelatedCriterionSatisfactions();
}
}
public void deleteCriterionSatisfaction(CriterionSatisfaction satisfaction)
throws InstanceNotFoundException {
workerCRUDController.getWorker().removeCriterionSatisfaction(
satisfaction);
workerModel.removeSatisfaction(satisfaction);
this.workerCRUDController.goToEditForm();
}

View file

@ -106,14 +106,15 @@ public class WorkerModel implements IWorkerModel {
}
}
public Set<CriterionSatisfaction> getCriterionSatisfactions(Worker worker) {
return worker.getAllSatisfactions();
}
@Transactional
@Transactional(readOnly = true)
public AddingSatisfactionResult addSatisfaction(ICriterionType<?> type,
CriterionSatisfaction original, CriterionSatisfaction edited) {
/* Check worker's version. */
Worker worker = getWorker();
resourceService.checkVersion(worker);
/* Add criterion satisfaction. */
edited.setResource(worker);
boolean previouslyContained = false;
if (previouslyContained = worker.contains(original)) {
@ -138,6 +139,42 @@ public class WorkerModel implements IWorkerModel {
return AddingSatisfactionResult.OK;
}
@Transactional(readOnly = true)
public void removeSatisfaction(CriterionSatisfaction satisfaction) {
/* Check worker's version. */
Worker worker = getWorker();
resourceService.checkVersion(worker);
/* Remove criterion satisfaction. */
worker.removeCriterionSatisfaction(satisfaction);
}
@Transactional(readOnly = true)
public void assignCriteria(Collection<? extends Criterion> criteria) {
/* Check worker's version. */
Worker worker = getWorker();
resourceService.checkVersion(worker);
/* Assign criteria. */
getLocalizationsAssigner().assign(criteria);
}
@Transactional(readOnly = true)
public void unassignSatisfactions(
Collection<? extends CriterionSatisfaction> satisfactions) {
/* Check worker's version. */
Worker worker = getWorker();
resourceService.checkVersion(worker);
/* Unassign criterion satisfactions. */
getLocalizationsAssigner().unassign(satisfactions);
}
private static class NullAssigner implements
IMultipleCriterionActiveAssigner {
@ -317,16 +354,6 @@ public class WorkerModel implements IWorkerModel {
}
@Override
public Worker findResource(long workerId) {
try {
return (Worker) resourceService.findResource(workerId);
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
}
}
@Override
@Transactional(readOnly = true)
public Map<ICriterionType<?>, Collection<Criterion>> getLaboralRelatedCriterions() {
Map<ICriterionType<?>, Collection<Criterion>> result = new HashMap<ICriterionType<?>, Collection<Criterion>>();
for (ICriterionType<?> type : laboralRelatedTypes) {
@ -336,12 +363,8 @@ public class WorkerModel implements IWorkerModel {
}
@Override
public List<CriterionSatisfaction> getLaboralRelatedCriterionSatisfactions(
Worker worker) {
Set<CriterionSatisfaction> result = new HashSet<CriterionSatisfaction>();
for (ICriterionType<?> criterionType : laboralRelatedTypes) {
result.addAll(worker.getSatisfactionsFor(criterionType));
}
public List<CriterionSatisfaction>
getLaboralRelatedCriterionSatisfactions() {
return worker.query().oneOf(laboralRelatedTypes).sortByStartDate()
.result();
}