Spring JpaRepositroy.save() 似乎不会在重复保存时抛出异常 [英] Spring JpaRepositroy.save() does not appear to throw exception on duplicate saves
问题描述
我目前正在使用 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
我尝试过的事情:
我已经尝试实现这个问题的答案,不幸的是我的代码从来没有遇到 DataAccesException 异常
I've tried implementing the answer from this question, unfortunately my code never ever hits the DataAccesException exception
再次对上述问题做出类似的回答.
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屋!