gpt4 book ai didi

java - 使用 Spring Data JPA 插入而不是更新

转载 作者:行者123 更新时间:2023-12-01 06:10:34 25 4
gpt4 key购买 nike

我有一个简单的模型。实体 A 与实体 B 具有一对多关系。它们使用关联表进行链接。我的用例是在简单的 Web 应用程序中获取/插入/更新实体:

  1. 以 JSON 形式获取实体 A。
  2. 将实体 A(即使未更改)保存。
  3. 违反约束:hibernate 尝试将现有行插入到关联表中。

为什么会发生这种情况? Hibernate 拥有确定是否应对父级及其子级进行合并或持久化所需的一切。为什么它不检查子级是否已经与父级链接?

Parent.java:

package com.example;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Version;

import lombok.EqualsAndHashCode;

@Entity
@EqualsAndHashCode(exclude = { "id" })
public class Parent {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Child> children = new HashSet<>();

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public Set<Child> getChildren() {
return children;
}

public void setChildren(Set<Child> children) {
this.children = children;
}

}

Child.java

package com.example;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Version;

import lombok.EqualsAndHashCode;

@Entity
@EqualsAndHashCode(exclude = { "id" })
public class Child {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private Long value;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public Long getValue() {
return value;
}

public void setValue(Long value) {
this.value = value;
}

}

ParentService.java:

package com.example;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.EntityManager;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class ParentService {

@Autowired
private ParentRepository parentRepository;

@Transactional
public Parent save(Parent parent) {
return parentRepository.save(parent);
}

}

ParentRepository.java:

package com.example;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ParentRepository extends JpaRepository<Parent, Long>{

}

有趣的是,当我添加 @Version 属性时,一切正常,但我找不到原因的解释。另一个解决方案是通过 id 获取 oldParent,只是为了获取 - 然后它也可以工作,即使没有 @Version,但是当我获取 oldParent 子级并使用 size() 初始化它时,再次出现不需要的插入。为什么这些东西还能起作用?它与 Hibernate 或 Spring Data JPA 存储库有关吗?

最佳答案

您写道:“它们使用关联表进行链接”

你确定吗?

ManyToOne 的默认映射是多方中的附加外键。在您的情况下,子表应该有一个附加字段“parent_id”,并且没有附加关联表。每个 child 都可以与一位 parent 精确关联。

也许您可以发布“hibernate 尝试将现有行插入关联表”的异常?

关于java - 使用 Spring Data JPA 插入而不是更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35964617/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com