这是我的存储库:
@Repository
public interface ProductRepo extends CrudRepository<Product,Integer> {
public List<Product> findAll();
public Product findById(int id);
}
我的实体豆:
@Entity
@Table(name = "product")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "product_id")
private Integer id;
@NotEmpty
@Column(name = "product_name")
private String productName;
控制器:
@PostMapping("/add-product")
String addProduct(@Validated @ModelAttribute("product")Product product, BindingResult bindingResult){
if (bindingResult.hasErrors()) {
System.out.println("has errors: " + bindingResult.toString());
}
System.out.println( "adding Product ..." );
productService.save(product);
return "redirect:/products/success";
这是我的观点
<form:form action="add-product" method="post" modelAttribute="product">
<label for="productName">Product Name</label>
<form:input path="productName" id="productName" type="text" placeholder="Add product name"/>
<form:errors path="productName" />
...
使用Hibernate SessionFactory存储到数据库时,它可以正常工作,如下所示:
// A shorter way to save customer
Session currentSession = sessionFactory.getCurrentSession();
currentSession.saveOrUpdate(customer);
但是当用Spring Data JPA替换它时,它会开始抛出异常并返回500个html页面,而不是像过去一样呈现错误字段。
抛出4个例外:
javax.validation.ConstraintViolationException: Validation failed for classes [com.luv2code.springdemo.entity.Product] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='must not be empty', propertyPath=productName, rootBeanClass=class com.luv2code.springdemo.entity.Product, messageTemplate='{javax.validation.constraints.NotEmpty.message}'}
]
javax.persistence.RollbackException: Error while committing the transaction
org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:77)
org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:71)
org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:536)
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
org.springframework.web.util.NestedServletException: 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
以前,在不使用JPA的情况下,验证错误消息显示在视图<form:errors />
中,不会作为500 http错误代码的异常抛出。我在这里想念什么?
答案 0 :(得分:2)
您看到的行为与Spring Data JPA无关,而是您从普通的hibernate(从代码片段判断)切换到JPA。
当使用JPA并使用JSR-303时,这些将一起工作以通过抛出验证异常来防止无效实体进入数据库。当使用普通的Hibernate时,这并没有发生(至少有例外情况不会传播)。
这是由于您编写了请求处理方法。如果模型中出现错误,您只需执行System.out
并愉快地继续该方法,您应该在那里做的是返回到原始视图(我假设为products/add-product
)。
@PostMapping("/add-product")
String addProduct(@Validated @ModelAttribute("product")Product product, BindingResult bindingResult){
if (bindingResult.hasErrors()) {
System.out.println("has errors: " + bindingResult.toString());
return "products/add-product";
}
System.out.println( "adding Product ..." );
productService.save(product);
return "redirect:/products/success";
}
基本上,由于JPA和javax.validation以统一的方式工作,您在处理错误的情况下失败,导致异常被抛出。