Extend current SQL translator in EclipseLink (#2383)

* Extend current SQL translator in EclipseLink

* Initialize translator in static block

Signed-off-by: strailov <Stanislav.Trailov@bosch.io>

* translation methods to static

Signed-off-by: strailov <Stanislav.Trailov@bosch.io>

* handle DataIntegrityViolation in rest core

Signed-off-by: strailov <Stanislav.Trailov@bosch.io>

---------

Signed-off-by: strailov <Stanislav.Trailov@bosch.io>
This commit is contained in:
Stanislav Trailov
2025-04-29 17:20:17 +03:00
committed by GitHub
parent 744ab70f97
commit 2a71f61cc2
4 changed files with 38 additions and 5 deletions

View File

@@ -15,6 +15,8 @@ import java.sql.SQLException;
import jakarta.persistence.PersistenceException;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
import org.springframework.jdbc.support.SQLErrorCodes;
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
import org.springframework.lang.NonNull;
import org.springframework.orm.jpa.JpaSystemException;
@@ -54,7 +56,20 @@ class HawkbitEclipseLinkJpaDialect extends EclipseLinkJpaDialect {
@Serial
private static final long serialVersionUID = 1L;
private static final SQLStateSQLExceptionTranslator SQLSTATE_EXCEPTION_TRANSLATOR = new SQLStateSQLExceptionTranslator();
private static final SQLErrorCodeSQLExceptionTranslator SQL_EXCEPTION_TRANSLATOR;
// providing list/set of codes which are not handled from the sql translator properly
private static final String[] DATA_INTEGRITY_VIOLATION_CODES = new String[] {
"1366"
};
static {
SQL_EXCEPTION_TRANSLATOR = new SQLErrorCodeSQLExceptionTranslator();
SQLErrorCodes codes = new SQLErrorCodes();
codes.setDataIntegrityViolationCodes(DATA_INTEGRITY_VIOLATION_CODES);
SQL_EXCEPTION_TRANSLATOR.setSqlErrorCodes(codes);
}
@Override
public DataAccessException translateExceptionIfPossible(@NonNull final RuntimeException ex) {
@@ -84,7 +99,8 @@ class HawkbitEclipseLinkJpaDialect extends EclipseLinkJpaDialect {
if (sqlException == null) {
return null;
}
return SQLSTATE_EXCEPTION_TRANSLATOR.translate("", null, sqlException);
return SQL_EXCEPTION_TRANSLATOR.translate("", null, sqlException);
}
private static SQLException findSqlException(final RuntimeException jpaSystemException) {

View File

@@ -24,7 +24,6 @@ import org.eclipse.hawkbit.repository.exception.ConcurrentModificationException;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException;
import org.springframework.core.Ordered;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.security.access.AccessDeniedException;
@@ -49,12 +48,10 @@ public class ExceptionMappingAspectHandler implements Ordered {
static {
MAPPED_EXCEPTION_ORDER.add(DuplicateKeyException.class);
MAPPED_EXCEPTION_ORDER.add(DataIntegrityViolationException.class);
MAPPED_EXCEPTION_ORDER.add(OptimisticLockingFailureException.class);
MAPPED_EXCEPTION_ORDER.add(AccessDeniedException.class);
EXCEPTION_MAPPING.put(DuplicateKeyException.class.getName(), EntityAlreadyExistsException.class.getName());
EXCEPTION_MAPPING.put(DataIntegrityViolationException.class.getName(), EntityAlreadyExistsException.class.getName());
EXCEPTION_MAPPING.put(OptimisticLockingFailureException.class.getName(), ConcurrentModificationException.class.getName());
EXCEPTION_MAPPING.put(AccessDeniedException.class.getName(), InsufficientPermissionException.class.getName());

View File

@@ -46,6 +46,10 @@
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>

View File

@@ -33,6 +33,7 @@ import org.eclipse.hawkbit.rest.util.FileStreamingFailedException;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.hateoas.config.EnableHypermediaSupport;
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
import org.springframework.http.HttpStatus;
@@ -272,6 +273,21 @@ public class RestConfiguration {
return new ResponseEntity<>(createExceptionInfo(new MultiPartFileUploadException(responseCause)), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler({DataIntegrityViolationException.class})
public ResponseEntity<ExceptionInfo> handleDataAccessException(final HttpServletRequest request, final DataIntegrityViolationException ex) {
if (log.isDebugEnabled()) {
logRequest(request, ex);
} else {
log.error("Handling exception {} of request {}", ex.getClass().getName(), request.getRequestURL());
}
final ExceptionInfo response = new ExceptionInfo();
response.setMessage("The data provided violates integrity rules. Please ensure all required fields are valid.");
response.setExceptionClass(ex.getClass().getName());
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}
private static HttpStatus getStatusOrDefault(final SpServerError error) {
return ERROR_TO_HTTP_STATUS.getOrDefault(error, DEFAULT_RESPONSE_STATUS);
}