Move constraint validation hoursgroup.code must be unique to OrderModel.save()

HoursGroup.code must be unique for each OrderElement. This constraint
was being validation in HoursGroup, as an Hibernate validation. This
validation was very slow has for each HoursGroup it was needed to check
against all other HoursGroup. I moved this validation to
OrderModel.save() and speed up the process, keeping the same
funcionality.

FEA: ItEr61S07PerformanceOrderEdition
This commit is contained in:
Diego Pino Garcia 2010-08-31 16:56:00 +02:00
parent 23d70111e0
commit 1207aa9198
5 changed files with 84 additions and 29 deletions

View file

@ -20,6 +20,10 @@
package org.navalplanner.business.orders.daos;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.Validate;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
@ -27,6 +31,7 @@ import org.hibernate.criterion.Restrictions;
import org.navalplanner.business.common.daos.IntegrationEntityDAO;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.Order;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
@ -88,4 +93,37 @@ public class HoursGroupDAO extends IntegrationEntityDAO<HoursGroup>
}
}
}
@Override
@Transactional(readOnly= true, propagation = Propagation.REQUIRES_NEW)
public HoursGroup findRepeatedHoursGroupCodeInDB(List<HoursGroup> hoursGroupList) {
final Map<String, HoursGroup> hoursGroups = createMapByCode(hoursGroupList);
final Map<String, HoursGroup> hoursGroupsInDB = createMapByCode(getAll());
for (String code : hoursGroups.keySet()) {
HoursGroup hoursGroup = hoursGroups.get(code);
HoursGroup hoursGroupInDB = hoursGroupsInDB.get(code);
// There's an element in the DB with the same code and it's a
// different element
if (hoursGroupInDB != null
&& !hoursGroupInDB.getId().equals(hoursGroup.getId())) {
return hoursGroup;
}
}
return null;
}
private List<HoursGroup> getAll() {
return list(HoursGroup.class);
}
private Map<String, HoursGroup> createMapByCode(List<HoursGroup> hoursGroups) {
Map<String, HoursGroup> result = new HashMap<String, HoursGroup>();
for (HoursGroup each: hoursGroups) {
final String code = each.getCode();
result.put(code, each);
}
return result;
}
}

View file

@ -21,6 +21,9 @@
package org.navalplanner.business.orders.daos;
import org.navalplanner.business.common.daos.IIntegrationEntityDAO;
import java.util.List;
import org.navalplanner.business.common.daos.IGenericDAO;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.orders.entities.HoursGroup;
@ -28,6 +31,7 @@ import org.navalplanner.business.orders.entities.HoursGroup;
* Contract for {@link HoursGroupDAO}
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Diego Pino Garcia <dpino@igalia.com>
*/
public interface IHoursGroupDAO extends IIntegrationEntityDAO<HoursGroup> {
@ -36,4 +40,12 @@ public interface IHoursGroupDAO extends IIntegrationEntityDAO<HoursGroup> {
HoursGroup findUniqueByCodeAnotherTransaction(HoursGroup hoursGroup)
throws InstanceNotFoundException;
/**
* Checks if there's another {@link HoursGroup} in DB which code is the same as
* some of the ones in order.hoursGroups
*
* @param order
* @return
*/
HoursGroup findRepeatedHoursGroupCodeInDB(List<HoursGroup> hoursGroupList);
}

View file

@ -33,7 +33,6 @@ import java.util.UUID;
import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.validator.AssertTrue;
import org.hibernate.validator.NotEmpty;
import org.hibernate.validator.NotNull;
import org.hibernate.validator.Valid;
@ -42,6 +41,7 @@ import org.navalplanner.business.common.Registry;
import org.navalplanner.business.common.daos.IIntegrationEntityDAO;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.orders.daos.IHoursGroupDAO;
import org.navalplanner.business.common.BaseEntity;
import org.navalplanner.business.requirements.entities.CriterionRequirement;
import org.navalplanner.business.requirements.entities.DirectCriterionRequirement;
import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement;
@ -396,27 +396,6 @@ public class HoursGroup extends IntegrationEntity implements Cloneable,
return false;
}
@AssertTrue(message = "hours group code is already being used")
public boolean checkConstraintUniqueCode() {
if (code == null) {
LOG.warn("Hours group code is null. "
+ "Not checking unique code since it would fail");
return true;
}
IHoursGroupDAO hoursGroupDAO = Registry.getHoursGroupDAO();
if (isNewObject()) {
return !hoursGroupDAO.existsByCodeAnotherTransaction(this);
} else {
try {
HoursGroup hoursGroup = hoursGroupDAO
.findUniqueByCodeAnotherTransaction(this);
return hoursGroup.getId().equals(getId());
} catch (InstanceNotFoundException e) {
return true;
}
}
}
public OrderLineTemplate getOrderLineTemplate() {
return orderLineTemplate;
}

View file

@ -451,19 +451,20 @@ public class Order extends OrderLineGroup {
}
}
@AssertTrue(message = "some code is repeated between hours group codes")
public boolean checkConstraintHoursGroupCodeNotRepeated() {
public HoursGroup findRepeatedHoursGroupCode() {
Set<String> codes = new HashSet<String>();
for (HoursGroup hoursGroup : getHoursGroups()) {
String code = hoursGroup.getCode();
if (codes.contains(code)) {
return false;
if (code != null) {
if (codes.contains(code)) {
return hoursGroup;
}
codes.add(code);
}
codes.add(code);
}
return true;
return null;
}
@Override

View file

@ -50,6 +50,7 @@ import org.navalplanner.business.externalcompanies.daos.IExternalCompanyDAO;
import org.navalplanner.business.externalcompanies.entities.ExternalCompany;
import org.navalplanner.business.labels.daos.ILabelDAO;
import org.navalplanner.business.labels.entities.Label;
import org.navalplanner.business.orders.daos.IHoursGroupDAO;
import org.navalplanner.business.orders.daos.IOrderDAO;
import org.navalplanner.business.orders.daos.IOrderElementDAO;
import org.navalplanner.business.orders.entities.HoursGroup;
@ -173,6 +174,9 @@ public class OrderModel implements IOrderModel {
@Autowired
private IOrderVersionDAO orderVersionDAO;
@Autowired
private IHoursGroupDAO hoursGroupDAO;
@Override
@Transactional(readOnly = true)
public List<Label> getLabels() {
@ -507,6 +511,7 @@ public class OrderModel implements IOrderModel {
private void saveOnTransaction(boolean newOrderVersionNeeded) {
checkConstraintOrderUniqueCode();
checkConstraintHoursGroupUniqueCode();
reattachCriterions();
reattachTasksForTasksSources();
@ -538,6 +543,26 @@ public class OrderModel implements IOrderModel {
calculateAdvancePercentageIncludingChildren(order);
}
private void checkConstraintHoursGroupUniqueCode() {
HoursGroup repeatedHoursGroup;
repeatedHoursGroup = order.findRepeatedHoursGroupCode();
if (repeatedHoursGroup != null) {
throw new ValidationException(_(
"Repeated Hours Group code {0} in Order {1}",
repeatedHoursGroup.getCode(), repeatedHoursGroup
.getParentOrderLine().getName()));
}
repeatedHoursGroup = hoursGroupDAO.findRepeatedHoursGroupCodeInDB(order.getHoursGroups());
if (repeatedHoursGroup != null) {
throw new ValidationException(_(
"Repeated Hours Group code {0} in Order {1}",
repeatedHoursGroup.getCode(), repeatedHoursGroup
.getParentOrderLine().getName()));
}
}
private void checkConstraintOrderUniqueCode() {
OrderElement repeatedOrder;