/** * {@inheritDoc} */ @Override public boolean isDirty(IEntity entity) { return isDirty(entity, false); }
private boolean isDirtyInDepth(IEntity entity, boolean includeComputed, IEntityRegistry alreadyTraversed) { alreadyTraversed.register(getComponentContract(entity), entity.getId(), entity); if (isDirty(entity, includeComputed)) { return true; } Map<String, Object> entityProps = entity.straightGetProperties(); for (Map.Entry<String, Object> property : entityProps.entrySet()) { Object propertyValue = property.getValue(); if (propertyValue instanceof IEntity) { if (isInitialized(propertyValue) && alreadyTraversed.get(getComponentContract((IEntity) propertyValue), ((IEntity) propertyValue).getId()) == null) { if (isDirtyInDepth((IEntity) propertyValue, includeComputed, alreadyTraversed)) { return true; } } } else if (propertyValue instanceof Collection<?>) { if (isInitialized(propertyValue)) { for (Object elt : ((Collection<?>) propertyValue)) { if (elt instanceof IEntity && alreadyTraversed.get(getComponentContract((IEntity) elt), ((IEntity) elt).getId()) == null) { if (isDirtyInDepth((IEntity) elt, includeComputed, alreadyTraversed)) { return true; } } } } } } return false; }
private <E extends IEntity> void checkBadMergeUsage(E entity) { if (isUnitOfWorkActive()) { if (isInitialized(entity) && entity.isPersistent() && isDirty(entity)) { String message = MessageFormatter.arrayFormat( "*BAD MERGE USAGE* An attempt is made to merge a UOW dirty entity ({})[{}] to the application session.\n" + "This will break transaction isolation since, if the transaction is rolled back," + " the UOW dirty state will be kept.\n" + "Dirty UOW entities will be automatically merged whenever the transaction is committed.", new Object[]{entity, getComponentContract(entity).getSimpleName()}).getMessage(); LOG.error(message); if (isThrowExceptionOnBadUsage()) { throw new BackendException("A bad usage has been detected on the backend controller." + "This is certainly an application coding problem:\n" + message); } } } }