I have next spring rest controller for handle my exception:
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public @ResponseBody
ExceptionResponseDTO hiberAnnotationExceptionHandler(ConstraintViolationException exception) {
return new ExceptionResponseDTO("Entity is null or we are out of range!", exception.getMessage(), ExceptionMapper.INSTANCE.exceptionToExceptionDTO(exception));
}
My entity class:
@Entity
public class Device {
@Id
@Column(name="name", nullable = false)
private String Name;
@Column(name = "send_date")
@NotNull
private Date sendDate;
}
I try to emulate ConstraintViolationException, so in my controller I use next code:
Device d = new Device();
d.setName("sdsdsd");
d.setSendDate(null);
deviceRepository.save(d);
And as result I receive next exception:
[dispatcherServlet]:? - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction] with root cause javax.validation.ConstraintViolationException: Validation failed for classes [com.entity.Device] during update time for groups [javax.validation.groups.Default, ] List of constraint violations:[ ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=sendDate, rootBeanClass=class com.entity.Device, messageTemplate='{javax.validation.constraints.NotNull.message}'} ]
So as you can see from stacktrace I receive TransactionSystemException first and because of this my ExceptionHandler method (hiberAnnotationExceptionHandler) doesn't call. So my question is how to emulate this exception (ConstraintViolationException)? Thanks in advance.
Exception thrown when an action would violate a constraint on repository structure. For example, when an attempt is made to persistently add an item to a node that would violate that node's node type.
hibernate. exception. ConstraintViolationException. This is by far the most common cause of DataIntegrityViolationException being thrown – the Hibernate ConstraintViolationException indicates that the operation has violated a database integrity constraint.
The most basic way of returning an error message from a REST API is to use the @ResponseStatus annotation. We can add the error message in the annotation's reason field. Although we can only return a generic error message, we can specify exception-specific error messages.
Reason for TransactionSystemException
If you go inside the code AbstractEntityManagerImpl.convert() method, you will see that by default it's not handling any specific exception like ConstraintViolation instead it just throws and wraps in PersistenceException.
Solution for correctly resolving your exception
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> <property name="jpaDialect" ref="jpaDialect"/> </bean> <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
HibernateJpaDialect catches those exception and converts to spring specific exceptions like this
if (ex instanceof ConstraintViolationException) { ConstraintViolationException jdbcEx = (ConstraintViolationException) ex; return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]; constraint [" + jdbcEx.getConstraintName() + "]", ex); }
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="packagesToScan" value="com.pack.model" /> <property name="persistenceUnitManager" ref="persistenceUnitManager"/> <property name="persistenceUnitName" value="entityManager"/> <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/> </bean> <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
@ExceptionHandler(DataIntegrityViolationException.class)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With