Spring data JPA - CrudRepository save() 上的 ConstraintViolationException

Posted

技术标签:

【中文标题】Spring data JPA - CrudRepository save() 上的 ConstraintViolationException【英文标题】:Spring data JPA - ConstraintViolationException on CrudRepository save() 【发布时间】:2018-08-15 14:26:48 【问题描述】:

我在使用 Spring data JPA(使用 Hibernate、Postgre SQL 和 jdbc)时遇到了问题。 我有 2 个实体,Texte 和 Annotation,以及 2 个扩展 CrudRepository 的存储库,TexteRepository 和 AnnotationRepository。 Annotation 与 Texte 具有多对一的关系。在控制器中,我正在做这样的事情:

Annotation annotation = new Annotation();
Texte texte = texteRepository.findOne(id);
if(texte != null) 
  annotation.setTexte(texte);
  annotationRepository.save(annotation);

在执行此操作时,我遇到了 ConstraintViolationException :

could not execute statement; SQL [n/a]; constraint [id_texte]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

我的理解是 Hibernate 不知道我的 texte 实体已经被持久化,所以它会尝试插入它。我来自 .NET,但我想说的是 texte 没有“附加”到同一个数据库上下文而不是注释。

这是我的实体声明(我只向您展示相关属性):

@Entity
@Getter
@Setter
public class Texte 
    @Id
    @GeneratedValue
    private Long id;
...


@Entity
@Getter
@Setter
@Audited
public class Annotation 
       @Id
       @GeneratedValue
       private Long id;

       @ManyToOne(fetch = FetchType.LAZY)
       @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
       private Texte texte;

    ...

非常感谢

克莱门特

【问题讨论】:

【参考方案1】:

在 Annotation 类中 Texte 的映射不正确,您需要定义一个列(即外键)链接两个表

【讨论】:

什么意思?我的模型中的所有关系都是这样声明的,使用 ManyToOne、OneToOne、ManyToMany... 如果您不指定外部列,它会自行创建一个 xxx_id 列。在我的例子中,我在我的数据库中看到了一个 texte_id 列,并且在 texte_id 和 Text 表中的 id 列之间存在一个约束。

以上是关于Spring data JPA - CrudRepository save() 上的 ConstraintViolationException的主要内容,如果未能解决你的问题,请参考以下文章

spring-data-jpa 和 spring-boot-starter-data-jpa 的区别

spring-data详解之spring-data-jpa:简单三步快速上手spring-data-jpa开发

spring data jpa怎么和solr整合

spring data jpa问题

Spring Data 系列 Spring+JPA(spring-data-commons)

spring-data-jpa软删除方案