我目前正在玩 Spring boot 1.4.2,其中我引入了 Spring-boot-starter-web 和 Spring-boot-starter-jpa。
我的主要问题是,当我保存一个新实体时,它工作正常(很酷)。
但是,如果我保存具有相同 ID 的新产品实体(例如重复条目),它不会引发异常。我期待 ConstrintViolationException 或类似的东西。
给定以下设置:
应用.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();
}
}
注意 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")
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 注释。
各种各样的:
弹簧启动:1.4.2
休眠 ORM:5.2.2.FINAL
无论我使用或不使用 @Transactional
注释控制器,都会发生此问题
底层数据库清楚地显示异常
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
我知道将数据访问内容分解到它自己的服务层而不是将其转储到控制器中更好(更常见)
控制器的语义不是 ReST
我尝试过的事情:
我已经尝试实现这个问题的答案,不幸的是我的代码从未遇到过 DataAccessException 异常
再次对上述问题做出类似的回答。
http://www.baeldung.com/spring-dataIntegrityviolationexception
我尝试将 bean 添加到我的 JPAconfig.java 类中,即:
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
但似乎什么也没有发生。
抱歉发了很长的帖子,提前联系
原文由 Verric 发布,翻译遵循 CC BY-SA 4.0 许可协议
我想您知道
CrudRepository.save()
用于插入和更新。如果 Id 不存在,那么它将被视为插入,如果 Id 存在,它将被视为更新。如果您将 Id 发送为 null,则可能会出现异常。由于除了
@Id
之外没有任何其他注释id
变量,唯一 ID 生成必须由您的代码处理,否则您需要使用@GeneratedValue
注释。