diff --git a/avni-server-api/src/main/java/org/avni/server/dao/CustomJpaRepositoryImpl.java b/avni-server-api/src/main/java/org/avni/server/dao/CustomJpaRepositoryImpl.java index fbb2d3a53..4a7e7f613 100644 --- a/avni-server-api/src/main/java/org/avni/server/dao/CustomJpaRepositoryImpl.java +++ b/avni-server-api/src/main/java/org/avni/server/dao/CustomJpaRepositoryImpl.java @@ -1,6 +1,8 @@ package org.avni.server.dao; import org.avni.server.domain.CHSEntity; +import org.avni.server.service.exception.ConstraintViolationExceptionAcrossOrganisations; +import org.hibernate.exception.ConstraintViolationException; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.domain.SliceImpl; @@ -9,9 +11,11 @@ import org.springframework.data.jpa.repository.support.SimpleJpaRepository; import javax.persistence.EntityManager; +import javax.persistence.PersistenceException; import javax.persistence.TypedQuery; import java.io.Serializable; import java.util.List; +import java.util.Objects; public class CustomJpaRepositoryImpl extends SimpleJpaRepository implements CustomCHSJpaRepository { @@ -37,4 +41,17 @@ private Slice readSlice(TypedQuery query, Pageable pageable, Specification } return new SliceImpl<>(content, pageable, hasNextPage); } + + + @Override + public S save(S entity) { + try { + return super.save(entity); + } catch (PersistenceException pe) { + if (Objects.isNull(entity.getId()) && pe.getCause() != null && pe.getCause().getClass().equals(ConstraintViolationException.class)) { + throw new ConstraintViolationExceptionAcrossOrganisations(String.format("Entity=> ID: %d, UUID: %s, Type:%s, User:%s, Msg: %s", entity.getId(), entity.getUuid(), entity.getClass().getCanonicalName(), entity.getLastModifiedByName(), pe.getMessage()), (ConstraintViolationException) pe.getCause()); + } + throw pe; + } + } } \ No newline at end of file diff --git a/avni-server-api/src/main/java/org/avni/server/service/exception/ConstraintViolationExceptionAcrossOrganisations.java b/avni-server-api/src/main/java/org/avni/server/service/exception/ConstraintViolationExceptionAcrossOrganisations.java new file mode 100644 index 000000000..544f0ef5e --- /dev/null +++ b/avni-server-api/src/main/java/org/avni/server/service/exception/ConstraintViolationExceptionAcrossOrganisations.java @@ -0,0 +1,9 @@ +package org.avni.server.service.exception; + +import org.hibernate.exception.ConstraintViolationException; + +public class ConstraintViolationExceptionAcrossOrganisations extends ConstraintViolationException { + public ConstraintViolationExceptionAcrossOrganisations(String message, ConstraintViolationException cve) { + super(message, cve.getSQLException(), cve.getSQL(), cve.getConstraintName()); + } +} \ No newline at end of file diff --git a/avni-server-api/src/main/java/org/avni/server/web/ErrorInterceptors.java b/avni-server-api/src/main/java/org/avni/server/web/ErrorInterceptors.java index 8c4d3b41e..247e29b96 100644 --- a/avni-server-api/src/main/java/org/avni/server/web/ErrorInterceptors.java +++ b/avni-server-api/src/main/java/org/avni/server/web/ErrorInterceptors.java @@ -5,6 +5,7 @@ import org.avni.server.domain.accessControl.AvniAccessException; import org.avni.server.domain.accessControl.AvniNoUserSessionException; import org.avni.server.framework.rest.RestControllerErrorResponse; +import org.avni.server.service.exception.ConstraintViolationExceptionAcrossOrganisations; import org.avni.server.util.BadRequestError; import org.avni.server.util.BugsnagReporter; import org.avni.server.web.util.ErrorBodyBuilder; @@ -91,6 +92,14 @@ public ResponseEntity fileUploadSizeLimitExceededError(Exception e) { return ResponseEntity.badRequest().body(String.format("Maximum upload file size exceeded; ensure file size is less than %s.", maxFileSize)); } + @ExceptionHandler(value = {ConstraintViolationExceptionAcrossOrganisations.class}) + public ResponseEntity entityUpsertErrorDueToConstraintViolationAcrossOrganisations(Exception e) { + bugsnagReporter.logAndReportToBugsnag(e); + return ResponseEntity.status(HttpStatus.CONFLICT).body( + String.format("Entity create or update failed due to constraint violation across organisations: %s", + errorBodyBuilder.getErrorMessageBody(e))); + } + @ExceptionHandler(value = {Exception.class}) public ResponseEntity unknownException(Exception e) { if (e instanceof BadRequestError) {