mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-02 19:27:57 +08:00
REST API should support optimistic locking via version field #1196
This commit is contained in:
parent
1c03eac407
commit
8736eda525
@ -196,11 +196,16 @@ public class EntityImportExport implements EntityImportExportAPI {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Entity> importEntities(Collection<? extends Entity> entities, EntityImportView importView) {
|
public Collection<Entity> importEntities(Collection<? extends Entity> entities, EntityImportView importView) {
|
||||||
return importEntities(entities, importView, false);
|
return importEntities(entities, importView, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Entity> importEntities(Collection<? extends Entity> entities, EntityImportView importView, boolean validate) {
|
public Collection<Entity> importEntities(Collection<? extends Entity> entities, EntityImportView importView, boolean validate) {
|
||||||
|
return importEntities(entities, importView, validate, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Entity> importEntities(Collection<? extends Entity> entities, EntityImportView importView, boolean validate, boolean optimisticLocking) {
|
||||||
List<ReferenceInfo> referenceInfoList = new ArrayList<>();
|
List<ReferenceInfo> referenceInfoList = new ArrayList<>();
|
||||||
CommitContext commitContext = new CommitContext();
|
CommitContext commitContext = new CommitContext();
|
||||||
commitContext.setSoftDeletion(false);
|
commitContext.setSoftDeletion(false);
|
||||||
@ -221,7 +226,7 @@ public class EntityImportExport implements EntityImportExportAPI {
|
|||||||
.setAuthorizationRequired(true);
|
.setAuthorizationRequired(true);
|
||||||
Entity dstEntity = dataManager.load(ctx);
|
Entity dstEntity = dataManager.load(ctx);
|
||||||
|
|
||||||
importEntity(srcEntity, dstEntity, importView, regularView, commitContext, referenceInfoList);
|
importEntity(srcEntity, dstEntity, importView, regularView, commitContext, referenceInfoList, optimisticLocking);
|
||||||
}
|
}
|
||||||
|
|
||||||
//2. references to existing entities are processed
|
//2. references to existing entities are processed
|
||||||
@ -273,6 +278,7 @@ public class EntityImportExport implements EntityImportExportAPI {
|
|||||||
* @param regularView view that was used for loading dstEntity
|
* @param regularView view that was used for loading dstEntity
|
||||||
* @param commitContext entities that must be commited or deleted will be set to the commitContext
|
* @param commitContext entities that must be commited or deleted will be set to the commitContext
|
||||||
* @param referenceInfoList list of referenceInfos for further processing
|
* @param referenceInfoList list of referenceInfos for further processing
|
||||||
|
* @param optimisticLocking whether the passed entity version should be validated before entity is persisted
|
||||||
* @return dstEntity that has fields values from the srcEntity
|
* @return dstEntity that has fields values from the srcEntity
|
||||||
*/
|
*/
|
||||||
protected Entity importEntity(Entity srcEntity,
|
protected Entity importEntity(Entity srcEntity,
|
||||||
@ -280,7 +286,8 @@ public class EntityImportExport implements EntityImportExportAPI {
|
|||||||
EntityImportView importView,
|
EntityImportView importView,
|
||||||
View regularView,
|
View regularView,
|
||||||
CommitContext commitContext,
|
CommitContext commitContext,
|
||||||
Collection<ReferenceInfo> referenceInfoList) {
|
Collection<ReferenceInfo> referenceInfoList,
|
||||||
|
boolean optimisticLocking) {
|
||||||
MetaClass metaClass = srcEntity.getMetaClass();
|
MetaClass metaClass = srcEntity.getMetaClass();
|
||||||
boolean createOp = false;
|
boolean createOp = false;
|
||||||
if (dstEntity == null) {
|
if (dstEntity == null) {
|
||||||
@ -317,27 +324,34 @@ public class EntityImportExport implements EntityImportExportAPI {
|
|||||||
if (BaseEntityInternalAccess.isRequired(dstSecurityState, propertyName) && srcEntity.getValue(propertyName) == null) {
|
if (BaseEntityInternalAccess.isRequired(dstSecurityState, propertyName) && srcEntity.getValue(propertyName) == null) {
|
||||||
throw new CustomValidationException(format("Attribute [%s] is required for entity %s", propertyName, srcEntity));
|
throw new CustomValidationException(format("Attribute [%s] is required for entity %s", propertyName, srcEntity));
|
||||||
}
|
}
|
||||||
if ((metaProperty.getRange().isDatatype() && !"version".equals(metaProperty.getName())) || metaProperty.getRange().isEnum()) {
|
if (metaProperty.getRange().isDatatype()) {
|
||||||
|
if (!"version".equals(metaProperty.getName())) {
|
||||||
|
dstEntity.setValue(propertyName, srcEntity.getValue(propertyName));
|
||||||
|
} else if (optimisticLocking){
|
||||||
|
dstEntity.setValue(propertyName, srcEntity.getValue(propertyName));
|
||||||
|
}
|
||||||
|
} else if (metaProperty.getRange().isEnum()) {
|
||||||
dstEntity.setValue(propertyName, srcEntity.getValue(propertyName));
|
dstEntity.setValue(propertyName, srcEntity.getValue(propertyName));
|
||||||
} else if (metaProperty.getRange().isClass()) {
|
} else if (metaProperty.getRange().isClass()) {
|
||||||
View regularPropertyView = regularView.getProperty(propertyName) != null ? regularView.getProperty(propertyName).getView() : null;
|
View regularPropertyView = regularView.getProperty(propertyName) != null ? regularView.getProperty(propertyName).getView() : null;
|
||||||
if (metadata.getTools().isEmbedded(metaProperty)) {
|
if (metadata.getTools().isEmbedded(metaProperty)) {
|
||||||
if (importViewProperty.getView() != null) {
|
if (importViewProperty.getView() != null) {
|
||||||
Entity embeddedEntity = importEmbeddedAttribute(srcEntity, dstEntity, createOp, importViewProperty, regularPropertyView, commitContext, referenceInfoList);
|
Entity embeddedEntity = importEmbeddedAttribute(srcEntity, dstEntity, createOp, importViewProperty, regularPropertyView,
|
||||||
|
commitContext, referenceInfoList, optimisticLocking);
|
||||||
dstEntity.setValue(propertyName, embeddedEntity);
|
dstEntity.setValue(propertyName, embeddedEntity);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (metaProperty.getRange().getCardinality()) {
|
switch (metaProperty.getRange().getCardinality()) {
|
||||||
case MANY_TO_MANY:
|
case MANY_TO_MANY:
|
||||||
importManyToManyCollectionAttribute(srcEntity, dstEntity, srcSecurityState,
|
importManyToManyCollectionAttribute(srcEntity, dstEntity, srcSecurityState,
|
||||||
importViewProperty, regularPropertyView, commitContext, referenceInfoList);
|
importViewProperty, regularPropertyView, commitContext, referenceInfoList, optimisticLocking);
|
||||||
break;
|
break;
|
||||||
case ONE_TO_MANY:
|
case ONE_TO_MANY:
|
||||||
importOneToManyCollectionAttribute(srcEntity, dstEntity, srcSecurityState,
|
importOneToManyCollectionAttribute(srcEntity, dstEntity, srcSecurityState,
|
||||||
importViewProperty, regularPropertyView, commitContext, referenceInfoList);
|
importViewProperty, regularPropertyView, commitContext, referenceInfoList, optimisticLocking);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
importReference(srcEntity, dstEntity, importViewProperty, regularPropertyView, commitContext, referenceInfoList);
|
importReference(srcEntity, dstEntity, importViewProperty, regularPropertyView, commitContext, referenceInfoList, optimisticLocking);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -367,14 +381,15 @@ public class EntityImportExport implements EntityImportExportAPI {
|
|||||||
EntityImportViewProperty importViewProperty,
|
EntityImportViewProperty importViewProperty,
|
||||||
View regularView,
|
View regularView,
|
||||||
CommitContext commitContext,
|
CommitContext commitContext,
|
||||||
Collection<ReferenceInfo> referenceInfoList) {
|
Collection<ReferenceInfo> referenceInfoList,
|
||||||
|
boolean optimisticLocking) {
|
||||||
Entity srcPropertyValue = srcEntity.getValue(importViewProperty.getName());
|
Entity srcPropertyValue = srcEntity.getValue(importViewProperty.getName());
|
||||||
Entity dstPropertyValue = dstEntity.getValue(importViewProperty.getName());
|
Entity dstPropertyValue = dstEntity.getValue(importViewProperty.getName());
|
||||||
if (importViewProperty.getView() == null) {
|
if (importViewProperty.getView() == null) {
|
||||||
ReferenceInfo referenceInfo = new ReferenceInfo(dstEntity, null, importViewProperty, srcPropertyValue, dstPropertyValue);
|
ReferenceInfo referenceInfo = new ReferenceInfo(dstEntity, null, importViewProperty, srcPropertyValue, dstPropertyValue);
|
||||||
referenceInfoList.add(referenceInfo);
|
referenceInfoList.add(referenceInfo);
|
||||||
} else {
|
} else {
|
||||||
dstPropertyValue = importEntity(srcPropertyValue, dstPropertyValue, importViewProperty.getView(), regularView, commitContext, referenceInfoList);
|
dstPropertyValue = importEntity(srcPropertyValue, dstPropertyValue, importViewProperty.getView(), regularView, commitContext, referenceInfoList, optimisticLocking);
|
||||||
dstEntity.setValue(importViewProperty.getName(), dstPropertyValue);
|
dstEntity.setValue(importViewProperty.getName(), dstPropertyValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -385,7 +400,8 @@ public class EntityImportExport implements EntityImportExportAPI {
|
|||||||
EntityImportViewProperty viewProperty,
|
EntityImportViewProperty viewProperty,
|
||||||
View regularView,
|
View regularView,
|
||||||
CommitContext commitContext,
|
CommitContext commitContext,
|
||||||
Collection<ReferenceInfo> referenceInfoList) {
|
Collection<ReferenceInfo> referenceInfoList,
|
||||||
|
boolean optimisticLocking) {
|
||||||
Collection<Entity> collectionValue = srcEntity.getValue(viewProperty.getName());
|
Collection<Entity> collectionValue = srcEntity.getValue(viewProperty.getName());
|
||||||
Collection<Entity> prevCollectionValue = dstEntity.getValue(viewProperty.getName());
|
Collection<Entity> prevCollectionValue = dstEntity.getValue(viewProperty.getName());
|
||||||
MetaProperty metaProperty = srcEntity.getMetaClass().getPropertyNN(viewProperty.getName());
|
MetaProperty metaProperty = srcEntity.getMetaClass().getPropertyNN(viewProperty.getName());
|
||||||
@ -397,7 +413,7 @@ public class EntityImportExport implements EntityImportExportAPI {
|
|||||||
.onCreate(e -> {
|
.onCreate(e -> {
|
||||||
if (!dstFilteredIds.contains(referenceToEntitySupport.getReferenceId(e))) {
|
if (!dstFilteredIds.contains(referenceToEntitySupport.getReferenceId(e))) {
|
||||||
Entity result = importEntity(e, null, viewProperty.getView(), regularView,
|
Entity result = importEntity(e, null, viewProperty.getView(), regularView,
|
||||||
commitContext, referenceInfoList);
|
commitContext, referenceInfoList, optimisticLocking);
|
||||||
if (inverseMetaProperty != null) {
|
if (inverseMetaProperty != null) {
|
||||||
result.setValue(inverseMetaProperty.getName(), dstEntity);
|
result.setValue(inverseMetaProperty.getName(), dstEntity);
|
||||||
}
|
}
|
||||||
@ -407,7 +423,7 @@ public class EntityImportExport implements EntityImportExportAPI {
|
|||||||
.onUpdate((src, dst) -> {
|
.onUpdate((src, dst) -> {
|
||||||
if (!dstFilteredIds.contains(referenceToEntitySupport.getReferenceId(src))) {
|
if (!dstFilteredIds.contains(referenceToEntitySupport.getReferenceId(src))) {
|
||||||
Entity result = importEntity(src, dst, viewProperty.getView(), regularView,
|
Entity result = importEntity(src, dst, viewProperty.getView(), regularView,
|
||||||
commitContext, referenceInfoList);
|
commitContext, referenceInfoList, optimisticLocking);
|
||||||
if (inverseMetaProperty != null) {
|
if (inverseMetaProperty != null) {
|
||||||
result.setValue(inverseMetaProperty.getName(), dstEntity);
|
result.setValue(inverseMetaProperty.getName(), dstEntity);
|
||||||
}
|
}
|
||||||
@ -435,7 +451,8 @@ public class EntityImportExport implements EntityImportExportAPI {
|
|||||||
EntityImportViewProperty viewProperty,
|
EntityImportViewProperty viewProperty,
|
||||||
View regularView,
|
View regularView,
|
||||||
CommitContext commitContext,
|
CommitContext commitContext,
|
||||||
Collection<ReferenceInfo> referenceInfoList) {
|
Collection<ReferenceInfo> referenceInfoList,
|
||||||
|
boolean optimisticLocking) {
|
||||||
Collection<Entity> collectionValue = srcEntity.getValue(viewProperty.getName());
|
Collection<Entity> collectionValue = srcEntity.getValue(viewProperty.getName());
|
||||||
Collection<Entity> prevCollectionValue = dstEntity.getValue(viewProperty.getName());
|
Collection<Entity> prevCollectionValue = dstEntity.getValue(viewProperty.getName());
|
||||||
MetaProperty metaProperty = srcEntity.getMetaClass().getPropertyNN(viewProperty.getName());
|
MetaProperty metaProperty = srcEntity.getMetaClass().getPropertyNN(viewProperty.getName());
|
||||||
@ -448,14 +465,14 @@ public class EntityImportExport implements EntityImportExportAPI {
|
|||||||
.onCreate(e -> {
|
.onCreate(e -> {
|
||||||
if (!dstFilteredIds.contains(referenceToEntitySupport.getReferenceId(e))) {
|
if (!dstFilteredIds.contains(referenceToEntitySupport.getReferenceId(e))) {
|
||||||
Entity result = importEntity(e, null, viewProperty.getView(), regularView,
|
Entity result = importEntity(e, null, viewProperty.getView(), regularView,
|
||||||
commitContext, referenceInfoList);
|
commitContext, referenceInfoList, optimisticLocking);
|
||||||
newCollectionValue.add(result);
|
newCollectionValue.add(result);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.onUpdate((src, dst) -> {
|
.onUpdate((src, dst) -> {
|
||||||
if (!dstFilteredIds.contains(referenceToEntitySupport.getReferenceId(src))) {
|
if (!dstFilteredIds.contains(referenceToEntitySupport.getReferenceId(src))) {
|
||||||
Entity result = importEntity(src, dst, viewProperty.getView(), regularView,
|
Entity result = importEntity(src, dst, viewProperty.getView(), regularView,
|
||||||
commitContext, referenceInfoList);
|
commitContext, referenceInfoList, optimisticLocking);
|
||||||
newCollectionValue.add(result);
|
newCollectionValue.add(result);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -483,7 +500,8 @@ public class EntityImportExport implements EntityImportExportAPI {
|
|||||||
EntityImportViewProperty importViewProperty,
|
EntityImportViewProperty importViewProperty,
|
||||||
View regularView,
|
View regularView,
|
||||||
CommitContext commitContext,
|
CommitContext commitContext,
|
||||||
Collection<ReferenceInfo> referenceInfoList) {
|
Collection<ReferenceInfo> referenceInfoList,
|
||||||
|
boolean optimisticLock) {
|
||||||
String propertyName = importViewProperty.getName();
|
String propertyName = importViewProperty.getName();
|
||||||
MetaProperty metaProperty = srcEntity.getMetaClass().getPropertyNN(propertyName);
|
MetaProperty metaProperty = srcEntity.getMetaClass().getPropertyNN(propertyName);
|
||||||
Entity srcEmbeddedEntity = srcEntity.getValue(propertyName);
|
Entity srcEmbeddedEntity = srcEntity.getValue(propertyName);
|
||||||
@ -527,12 +545,12 @@ public class EntityImportExport implements EntityImportExportAPI {
|
|||||||
View propertyRegularView = regularView.getProperty(propertyName) != null ? regularView.getProperty(propertyName).getView() : null;
|
View propertyRegularView = regularView.getProperty(propertyName) != null ? regularView.getProperty(propertyName).getView() : null;
|
||||||
if (metaProperty.getRange().getCardinality() == Range.Cardinality.ONE_TO_MANY) {
|
if (metaProperty.getRange().getCardinality() == Range.Cardinality.ONE_TO_MANY) {
|
||||||
importOneToManyCollectionAttribute(srcEmbeddedEntity, dstEmbeddedEntity, srcSecurityState,
|
importOneToManyCollectionAttribute(srcEmbeddedEntity, dstEmbeddedEntity, srcSecurityState,
|
||||||
vp, propertyRegularView, commitContext, referenceInfoList);
|
vp, propertyRegularView, commitContext, referenceInfoList, optimisticLock);
|
||||||
} else if (metaProperty.getRange().getCardinality() == Range.Cardinality.MANY_TO_MANY) {
|
} else if (metaProperty.getRange().getCardinality() == Range.Cardinality.MANY_TO_MANY) {
|
||||||
importManyToManyCollectionAttribute(srcEmbeddedEntity, dstEmbeddedEntity, srcSecurityState,
|
importManyToManyCollectionAttribute(srcEmbeddedEntity, dstEmbeddedEntity, srcSecurityState,
|
||||||
vp, propertyRegularView, commitContext, referenceInfoList);
|
vp, propertyRegularView, commitContext, referenceInfoList, optimisticLock);
|
||||||
} else {
|
} else {
|
||||||
importReference(srcEmbeddedEntity, dstEmbeddedEntity, vp, propertyRegularView, commitContext, referenceInfoList);
|
importReference(srcEmbeddedEntity, dstEmbeddedEntity, vp, propertyRegularView, commitContext, referenceInfoList, optimisticLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,4 +69,9 @@ public interface EntityImportExportAPI {
|
|||||||
* See documentation for {@link EntityImportExportService#importEntities(Collection, EntityImportView, boolean)}
|
* See documentation for {@link EntityImportExportService#importEntities(Collection, EntityImportView, boolean)}
|
||||||
*/
|
*/
|
||||||
Collection<Entity> importEntities(Collection<? extends Entity> entities, EntityImportView importView, boolean validate);
|
Collection<Entity> importEntities(Collection<? extends Entity> entities, EntityImportView importView, boolean validate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See documentation for {@link EntityImportExportService#importEntities(Collection, EntityImportView, boolean, boolean)}
|
||||||
|
*/
|
||||||
|
Collection<Entity> importEntities(Collection<? extends Entity> entities, EntityImportView importView, boolean validate, boolean optimisticLocking);
|
||||||
}
|
}
|
||||||
|
@ -69,4 +69,9 @@ public class EntityImportExportServiceBean implements EntityImportExportService
|
|||||||
public Collection<Entity> importEntities(Collection<? extends Entity> entities, EntityImportView importView, boolean validate) {
|
public Collection<Entity> importEntities(Collection<? extends Entity> entities, EntityImportView importView, boolean validate) {
|
||||||
return entityImportExport.importEntities(entities, importView, validate);
|
return entityImportExport.importEntities(entities, importView, validate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Entity> importEntities(Collection<? extends Entity> entities, EntityImportView importView, boolean validate, boolean optimisticLocking) {
|
||||||
|
return entityImportExport.importEntities(entities, importView, validate, optimisticLocking);
|
||||||
|
}
|
||||||
}
|
}
|
@ -120,4 +120,21 @@ public interface EntityImportExportService {
|
|||||||
* @return a collection of entities that have been imported
|
* @return a collection of entities that have been imported
|
||||||
*/
|
*/
|
||||||
Collection<Entity> importEntities(Collection<? extends Entity> entities, EntityImportView importView, boolean validate);
|
Collection<Entity> importEntities(Collection<? extends Entity> entities, EntityImportView importView, boolean validate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persists entities according to the rules, described by the {@code entityImportView} parameter. If the entity is
|
||||||
|
* not present in the database, it will be saved. Otherwise the fields of the existing entity that are in the {@code
|
||||||
|
* entityImportView} will be updated.
|
||||||
|
* <p>
|
||||||
|
* If the view contains a property for composition attribute then all composition collection members that are absent
|
||||||
|
* in the passed entity will be removed.
|
||||||
|
*
|
||||||
|
* @param importView {@code EntityImportView} with the rules that describes how entities should be persisted.
|
||||||
|
* @param validate whether the passed entities should be validated by the {@link com.haulmont.cuba.core.global.BeanValidation}
|
||||||
|
* mechanism before entities are persisted
|
||||||
|
* @param optimisticLocking whether the passed entities versions should be validated before entities are persisted
|
||||||
|
* @return a collection of entities that have been imported
|
||||||
|
*/
|
||||||
|
Collection<Entity> importEntities(Collection<? extends Entity> entities, EntityImportView importView, boolean validate,
|
||||||
|
boolean optimisticLocking);
|
||||||
}
|
}
|
||||||
|
@ -66,4 +66,10 @@ public interface RestApiConfig extends Config {
|
|||||||
@DefaultBoolean(true)
|
@DefaultBoolean(true)
|
||||||
boolean getTokenMaskingEnabled();
|
boolean getTokenMaskingEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return whether the passed entities versions should be validated before entities are persisted
|
||||||
|
*/
|
||||||
|
@Property("cuba.rest.optimisticLockingEnabled")
|
||||||
|
@DefaultBoolean(false)
|
||||||
|
boolean getOptimisticLockingEnabled();
|
||||||
}
|
}
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.haulmont.restapi.controllers;
|
package com.haulmont.restapi.controllers;
|
||||||
|
|
||||||
|
import com.haulmont.cuba.core.global.RemoteException;
|
||||||
import com.haulmont.cuba.core.global.RowLevelSecurityException;
|
import com.haulmont.cuba.core.global.RowLevelSecurityException;
|
||||||
import com.haulmont.cuba.core.global.validation.CustomValidationException;
|
import com.haulmont.cuba.core.global.validation.CustomValidationException;
|
||||||
import com.haulmont.cuba.core.global.validation.MethodParametersValidationException;
|
import com.haulmont.cuba.core.global.validation.MethodParametersValidationException;
|
||||||
@ -23,6 +24,7 @@ import com.haulmont.cuba.core.global.validation.MethodResultValidationException;
|
|||||||
import com.haulmont.restapi.exception.ConstraintViolationInfo;
|
import com.haulmont.restapi.exception.ConstraintViolationInfo;
|
||||||
import com.haulmont.restapi.exception.ErrorInfo;
|
import com.haulmont.restapi.exception.ErrorInfo;
|
||||||
import com.haulmont.restapi.exception.RestAPIException;
|
import com.haulmont.restapi.exception.RestAPIException;
|
||||||
|
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
@ -119,6 +121,19 @@ public class RestControllerExceptionHandler {
|
|||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseEntity<ErrorInfo> handleException(Exception e) {
|
public ResponseEntity<ErrorInfo> handleException(Exception e) {
|
||||||
log.error("Exception in REST controller", e);
|
log.error("Exception in REST controller", e);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<Throwable> list = ExceptionUtils.getThrowableList(e);
|
||||||
|
for (Throwable throwable : list) {
|
||||||
|
if (throwable instanceof RemoteException) {
|
||||||
|
RemoteException remoteException = (RemoteException) throwable;
|
||||||
|
for (RemoteException.Cause cause : remoteException.getCauses()) {
|
||||||
|
if (Objects.equals("javax.persistence.OptimisticLockException", cause.getClassName())) {
|
||||||
|
ErrorInfo errorInfo = new ErrorInfo("Optimistic lock", cause.getMessage());
|
||||||
|
return new ResponseEntity<>(errorInfo, HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
ErrorInfo errorInfo = new ErrorInfo("Server error", "");
|
ErrorInfo errorInfo = new ErrorInfo("Server error", "");
|
||||||
return new ResponseEntity<>(errorInfo, HttpStatus.INTERNAL_SERVER_ERROR);
|
return new ResponseEntity<>(errorInfo, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import com.haulmont.cuba.core.entity.*;
|
|||||||
import com.haulmont.cuba.core.global.*;
|
import com.haulmont.cuba.core.global.*;
|
||||||
import com.haulmont.cuba.security.entity.EntityOp;
|
import com.haulmont.cuba.security.entity.EntityOp;
|
||||||
import com.haulmont.restapi.common.RestControllerUtils;
|
import com.haulmont.restapi.common.RestControllerUtils;
|
||||||
|
import com.haulmont.restapi.config.RestApiConfig;
|
||||||
import com.haulmont.restapi.data.CreatedEntityInfo;
|
import com.haulmont.restapi.data.CreatedEntityInfo;
|
||||||
import com.haulmont.restapi.data.EntitiesSearchResult;
|
import com.haulmont.restapi.data.EntitiesSearchResult;
|
||||||
import com.haulmont.restapi.exception.RestAPIException;
|
import com.haulmont.restapi.exception.RestAPIException;
|
||||||
@ -84,6 +85,9 @@ public class EntitiesControllerManager {
|
|||||||
@Inject
|
@Inject
|
||||||
protected RestFilterParser restFilterParser;
|
protected RestFilterParser restFilterParser;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected RestApiConfig restApiConfig;
|
||||||
|
|
||||||
public String loadEntity(String entityName,
|
public String loadEntity(String entityName,
|
||||||
String entityId,
|
String entityId,
|
||||||
@Nullable String viewName,
|
@Nullable String viewName,
|
||||||
@ -330,7 +334,8 @@ public class EntitiesControllerManager {
|
|||||||
EntityImportView entityImportView = entityImportViewBuilderAPI.buildFromJson(entityJson, metaClass);
|
EntityImportView entityImportView = entityImportViewBuilderAPI.buildFromJson(entityJson, metaClass);
|
||||||
Collection<Entity> importedEntities;
|
Collection<Entity> importedEntities;
|
||||||
try {
|
try {
|
||||||
importedEntities = entityImportExportService.importEntities(Collections.singletonList(entity), entityImportView, true);
|
importedEntities = entityImportExportService.importEntities(Collections.singletonList(entity),
|
||||||
|
entityImportView, true, restApiConfig.getOptimisticLockingEnabled());
|
||||||
importedEntities.forEach(it-> restControllerUtils.applyAttributesSecurity(it));
|
importedEntities.forEach(it-> restControllerUtils.applyAttributesSecurity(it));
|
||||||
} catch (EntityImportException e) {
|
} catch (EntityImportException e) {
|
||||||
throw new RestAPIException("Entity update failed", e.getMessage(), HttpStatus.BAD_REQUEST, e);
|
throw new RestAPIException("Entity update failed", e.getMessage(), HttpStatus.BAD_REQUEST, e);
|
||||||
|
Loading…
Reference in New Issue
Block a user