使用Spring Data JPA

时间:2018-05-16 11:56:37

标签: spring spring-mvc spring-data-jpa

这是我的存储库:

@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错误代码的异常抛出。我在这里想念什么?

1 个答案:

答案 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以统一的方式工作,您在处理错误的情况下失败,导致异常被抛出。