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

问题描述

我目前正在使用Spring boot 1.4.2,其中我已经使用了Spring-boot-starter-web和Spring-boot-starter-jpa。



我的主要问题是,当我保存新实体时,它工作正常(非常酷)。



但是,如果我保存具有相同ID的新产品实体(例如,重复的条目),它不会抛出异常。我期待ConstrintViolationException或类似的东西。



给定以下设置:



Application.java

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

ProductRepository.java

  @Repository 
公共接口ProductRepository扩展了JpaRepository< Product,String> {}

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在相同的包。



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

  @Entity(name =product)
@Getter
@Setter
@AllArgsConstructor
@EqualsAndHashCode(of =id)
公共类产品{

protected Product(){/ * jpa构造函数* /}

@ Id
private String id;

@Column
private String name;

@Column
private Long price;

@Column
private Boolean taxable;
}

getter,setter和equalsHashcode ..是注释。



其他:



春季启动:1.4.2



Hibernate ORM:5.2.2.FINAL



无论我是否使用 @Transactional



注释控制器,无论是否注释控制器都会出现此问题。基础数据库显示异常明显

  2016-11-15 18:03:49 AEDT [40794-1] verric @ stuff错误:重复键值违反唯一约束product_pkey
2016-11-15 18:03:49 AEDT [40794-2] verric @ stuff详情:Key(id)=(test001)已存在

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



控制器的语义不是ReST



我试过的东西:





再次对上述问题做出类似回应。





  @Bean 
public PersistenceExceptionTranslationPostProcessor exceptionTranslation( ){
返回新的PersistenceExceptionTranslationPos tProcessor();
}

但似乎没有任何事情发生。



很抱歉很长的帖子,ty提前

解决方案

我想你知道 CrudRepository.save()用于插入和更新。如果Id不存在,那么如果Id存在则它将被视为插入,它将被视为更新。如果您将Id发送为空,则可能会出现例外情况。



因为除了 @Id id 变量上,唯一ID生成必须由您的代码处理,否则您需要使用 @GeneratedValue 注释。


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).

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.

Given the following set up:

Application.java

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

ProductRepository.java

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

JpaConfig.java

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

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

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

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());
        }
    }
}

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;
}

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

Miscellaneous:

Spring boot : 1.4.2

Hibernate ORM: 5.2.2.FINAL

This issue happens regardless if I annotate the controller with or without @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

The semantics of the controller aren't ReST

Things I've tried:

Spring CrudRepository exceptions

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

Does Spring JPA throw an error if save function is unsuccessful?

Again similar response to the question above.

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

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

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

But nothing seemed to happen.

Sorry for long post, ty in advance

解决方案

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.

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()似乎不会在重复保存时抛出异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-26 07:38