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>{ 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); 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 E find(PK id) throws InstanceNotFoundException;
public boolean exists(PK id); public boolean exists(PK id);

View file

@ -6,6 +6,7 @@ import java.util.List;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.SessionFactory; import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections; 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") @SuppressWarnings("unchecked")
public E find(PK id) throws InstanceNotFoundException { public E find(PK id) throws InstanceNotFoundException {

View file

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

View file

@ -23,6 +23,14 @@ public interface ResourceService {
*/ */
public void saveResource(Resource resource); 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) public Resource findResource(Long resourceId)
throws InstanceNotFoundException; throws InstanceNotFoundException;

View file

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

View file

@ -3,7 +3,6 @@ package org.navalplanner.web.resources.worker;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.navalplanner.business.common.exceptions.ValidationException; import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.Criterion;
@ -31,14 +30,9 @@ public interface IWorkerModel {
boolean isCreating(); boolean isCreating();
Set<CriterionSatisfaction> getCriterionSatisfactions(Worker worker);
Worker findResource(long workerId);
Map<ICriterionType<?>, Collection<Criterion>> getLaboralRelatedCriterions(); Map<ICriterionType<?>, Collection<Criterion>> getLaboralRelatedCriterions();
List<CriterionSatisfaction> getLaboralRelatedCriterionSatisfactions( List<CriterionSatisfaction> getLaboralRelatedCriterionSatisfactions();
Worker worker);
public enum AddingSatisfactionResult { public enum AddingSatisfactionResult {
OK, SATISFACTION_WRONG, DONT_COMPLY_OVERLAPPING_RESTRICTIONS; OK, SATISFACTION_WRONG, DONT_COMPLY_OVERLAPPING_RESTRICTIONS;
@ -48,4 +42,11 @@ public interface IWorkerModel {
CriterionSatisfaction originalSatisfaction, CriterionSatisfaction originalSatisfaction,
CriterionSatisfaction edited); 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 @Override
public void onEvent(Event event) throws Exception { public void onEvent(Event event) throws Exception {
workerModel.getLocalizationsAssigner().unassign( workerModel.unassignSatisfactions(
extractValuesOf(activeSatisfactions.getSelectedItems(), extractValuesOf(activeSatisfactions.getSelectedItems(),
CriterionSatisfaction.class)); CriterionSatisfaction.class));
reloadLists(); reloadLists();
@ -84,7 +84,7 @@ public class LocalizationsController extends GenericForwardComposer {
public void onEvent(Event event) throws Exception { public void onEvent(Event event) throws Exception {
Set<Listitem> selectedItems = criterionsNotAssigned Set<Listitem> selectedItems = criterionsNotAssigned
.getSelectedItems(); .getSelectedItems();
workerModel.getLocalizationsAssigner().assign( workerModel.assignCriteria(
extractValuesOf(selectedItems, Criterion.class)); extractValuesOf(selectedItems, Criterion.class));
reloadLists(); reloadLists();
} }

View file

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

View file

@ -106,14 +106,15 @@ public class WorkerModel implements IWorkerModel {
} }
} }
public Set<CriterionSatisfaction> getCriterionSatisfactions(Worker worker) { @Transactional(readOnly = true)
return worker.getAllSatisfactions();
}
@Transactional
public AddingSatisfactionResult addSatisfaction(ICriterionType<?> type, public AddingSatisfactionResult addSatisfaction(ICriterionType<?> type,
CriterionSatisfaction original, CriterionSatisfaction edited) { CriterionSatisfaction original, CriterionSatisfaction edited) {
/* Check worker's version. */
Worker worker = getWorker(); Worker worker = getWorker();
resourceService.checkVersion(worker);
/* Add criterion satisfaction. */
edited.setResource(worker); edited.setResource(worker);
boolean previouslyContained = false; boolean previouslyContained = false;
if (previouslyContained = worker.contains(original)) { if (previouslyContained = worker.contains(original)) {
@ -138,6 +139,42 @@ public class WorkerModel implements IWorkerModel {
return AddingSatisfactionResult.OK; 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 private static class NullAssigner implements
IMultipleCriterionActiveAssigner { IMultipleCriterionActiveAssigner {
@ -317,16 +354,6 @@ public class WorkerModel implements IWorkerModel {
} }
@Override @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() { public Map<ICriterionType<?>, Collection<Criterion>> getLaboralRelatedCriterions() {
Map<ICriterionType<?>, Collection<Criterion>> result = new HashMap<ICriterionType<?>, Collection<Criterion>>(); Map<ICriterionType<?>, Collection<Criterion>> result = new HashMap<ICriterionType<?>, Collection<Criterion>>();
for (ICriterionType<?> type : laboralRelatedTypes) { for (ICriterionType<?> type : laboralRelatedTypes) {
@ -336,12 +363,8 @@ public class WorkerModel implements IWorkerModel {
} }
@Override @Override
public List<CriterionSatisfaction> getLaboralRelatedCriterionSatisfactions( public List<CriterionSatisfaction>
Worker worker) { getLaboralRelatedCriterionSatisfactions() {
Set<CriterionSatisfaction> result = new HashSet<CriterionSatisfaction>();
for (ICriterionType<?> criterionType : laboralRelatedTypes) {
result.addAll(worker.getSatisfactionsFor(criterionType));
}
return worker.query().oneOf(laboralRelatedTypes).sortByStartDate() return worker.query().oneOf(laboralRelatedTypes).sortByStartDate()
.result(); .result();
} }