Spring JpaRepositroy.save() 似乎不会在重复保存时抛出异常 [英] Spring JpaRepositroy.save() does not appear to throw exception on duplicate saves

查看:43
本文介绍了Spring JpaRepositroy.save() 似乎不会在重复保存时抛出异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用 Spring boot 1.4.2,其中我引入了 Spring-boot-starter-web 和 Spring-boot-starter-jpa.

I'm currently playing around on Spring boot 1.4.2 in which I've pulled in Spring-boot-starter-web and Spring-boot-starter-jpa.

我的主要问题是,当我保存一个新实体时,它工作正常(一切都很酷).

My main issue is that when I save a new entity it works fine (all cool).

但是,如果我用相同的 id 保存一个新的产品实体(例如重复的条目),它不会抛出异常.我期待 ConstraintViolationException 或类似的东西.

However if I save a new product entity with the same id (eg a duplicate entry), it does not throw an exception. I was expecting ConstrintViolationException or something similar.

鉴于以下设置:

应用程序.java

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

ProductRepository.java

ProductRepository.java

@Repository
public interface ProductRepository extends JpaRepository<Product, String> {}

JpaConfig.java

JpaConfig.java

@Configuration
@EnableJpaRepositories(basePackages = "com.verric.jpa.repository" )
@EntityScan(basePackageClasses ="com.verric.jpa")
@EnableTransactionManagement
public class JpaConfig {

    @Bean
    JpaTransactionManager transactionManager() {
        return new JpaTransactionManager();
    }
}

注意 JpaConfig.java 和 Application.java 在同一个包中.

Note JpaConfig.java and Application.java are in the same package.

ProductController.java

ProductController.java

@RestController
@RequestMapping(path = "/product")
public class ProductController {

    @Autowired
    ProductRepository productRepository;

    @PostMapping("createProduct")
    public void handle(@RequestBody @Valid CreateProductRequest request) {
        Product product = new Product(request.getId(), request.getName(), request.getPrice(), request.isTaxable());
        try {
            productRepository.save(product);
        } catch (DataAccessException ex) {
            System.out.println(ex.getCause().getMessage());
        }
    }
}

最后是 Product.java

and finally Product.java

@Entity(name = "product")
@Getter
@Setter
@AllArgsConstructor
@EqualsAndHashCode(of = "id")
public class Product {

    protected Product() { /* jpa constructor*/ }

    @Id
    private String id;

    @Column
    private String name;

    @Column
    private Long price;

    @Column
    private Boolean taxable;
}

getter、setter 和 equalsHashcode.. 是 lombok 注释.

The getter, setter and equalsHashcode.. are lombok annotations.

其他:

春季启动:1.4.2

休眠 ORM:5.2.2.FINAL

Hibernate ORM: 5.2.2.FINAL

无论我是否使用 @Transactional

底层数据库清楚地显示异常

The underlying db shows the exception clearly

2016-11-15 18:03:49 AEDT [40794-1] verric@stuff ERROR:  duplicate key value violates unique constraint "product_pkey"
2016-11-15 18:03:49 AEDT [40794-2] verric@stuff DETAIL:  Key (id)=(test001) already exists

我知道将数据访问内容分解到自己的服务层而不是将其转储到控制器中更好(更常见)

I know that is better (more common) to break the data access stuff into its own service layer instead of dumping it in the controller

控制器的语义不是 ReST

The semantics of the controller aren't ReST

我尝试过的事情:

Spring CrudRepository 异常

我已经尝试实现这个问题的答案,不幸的是我的代码从来没有遇到 DataAccesException 异常

I've tried implementing the answer from this question, unfortunately my code never ever hits the DataAccesException exception

Spring JPA 是否抛出错误,如果保存功能不成功?

再次对上述问题做出类似的回答.

Again similar response to the question above.

http://www.baeldung.com/spring-dataIntegrityviolationexception

我尝试将 bean 添加到我的 JPAconfig.java 类中:

I tried adding the bean to my JPAconfig.java class that is:

   @Bean
   public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
      return new PersistenceExceptionTranslationPostProcessor();
   }

但似乎什么也没发生.

抱歉,帖子太长了,请提前

Sorry for long post, ty in advance

推荐答案

我想你知道 CrudRepository.save() 用于插入和更新.如果 Id 不存在,那么它将被视为插入,如果 Id 存在,它将被视为更新.如果您将 Id 发送为 null,您可能会收到异常.

I think you are aware of CrudRepository.save() is used for both insert and update. If an Id is non existing then it will considered an insert if Id is existing it will be considered update. You may get an Exception if your send the Id as null.

由于您的 id 变量上除了 @Id 之外没有任何其他注释,因此唯一 ID 生成必须由您的代码处理,否则您需要使用 @GeneratedValue 注释.

Since you don't have any other annotations apart from @Id on your id variable, The Unique Id generation must be handled by your code Or else you need to make use of @GeneratedValue annotation.

这篇关于Spring JpaRepositroy.save() 似乎不会在重复保存时抛出异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆