我有下一个春季休息控制器来处理我的异常:
@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));
}
我的实体类:
@Entity
public class Device {
@Id
@Column(name="name", nullable = false)
private String Name;
@Column(name = "send_date")
@NotNull
private Date sendDate;
}
我尝试模拟 ConstraintViolationException ,所以在我的控制器中我使用下一个代码:
Device d = new Device();
d.setName("sdsdsd");
d.setSendDate(null);
deviceRepository.save(d);
结果我收到了下一个例外:
[DispatcherServlet的]:? - Servlet的Servlet.service() 路径[]的上下文中的[dispatcherServlet]抛出异常[Request 处理失败;嵌套异常是 org.springframework.transaction.TransactionSystemException:无法 提交JPA事务;嵌套异常是 javax.persistence.RollbackException:提交时出错 具有根本原因的交易] javax.validation.ConstraintViolationException:验证失败 课程[com.entity.Device] 在组的更新时间[javax.validation.groups.Default,]列表 违反约束条件:[ ConstraintViolationImpl {interpolatedMessage ='可能不为空', propertyPath = sendDate,rootBeanClass = class com.entity.Device, messageTemplate =' {javax.validation.constraints.NotNull.message}'}]
从堆栈跟踪中我可以看到,我首先收到 TransactionSystemException ,因此我的 ExceptionHandler 方法( hiberAnnotationExceptionHandler )没有呼叫。所以我的问题是如何模拟这个异常( ConstraintViolationException )? 提前谢谢。
答案 0 :(得分:3)
TransactionSystemException的原因
如果你进入代码AbstractEntityManagerImpl.convert()方法, 您将看到默认情况下它不处理任何特定的异常,如ConstraintViolation,而只是抛出并包装在PersistenceException中。
正确解决异常的解决方案
<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捕获这些异常,并转换为像这样的弹簧特定异常
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)
答案 1 :(得分:-2)
尝试重现下一步:
@Bean public MethodValidationPostProcessor methodValidationPostProcessor() { return new MethodValidationPostProcessor(); }
使用@Validated
使用
@Pattern(regexp = "\\d+") @RequestParam String param
如果您想使用该实体。做类似
@Valid @RequestBody Device device
在你的方法中。 您可以跳过之前的所有步骤。