【问题标题】:One to Many relationship, how to save or update data in spring boot一对多关系,如何在spring boot中保存或更新数据
【发布时间】:2021-12-28 14:44:23
【问题描述】:

我正在为我工​​作的公司构建一个 API,这是我第一次使用 Spring Boot,所以我遇到了一些问题。

我有 2 个班级,Compania(家长)和 Office(孩子)。 Compania 类与 Office 具有 OneToMany 关系,Office 具有 ManyToOne,我正在努力寻找如何添加一些孩子或编辑其中一个。现在我的课程如下:

公司(母公司)

@Entity(name = "Compania")
@Table(
    name = "compania"
)
public class Compania {
    @Id
    @SequenceGenerator(
        name = "compania_sequence",
        sequenceName = "compania_sequence",
        allocationSize = 1
    )
    @GeneratedValue(
        strategy = GenerationType.SEQUENCE,
        generator = "compania_sequence"
    )
    @Column(
        nullable = false
    )
    private Long id;


    @Column(
        name = "name",
        nullable = false,
        unique = true
    )
    private String name;

    @Column(
        name = "dominio",
        nullable = true
    )
    private String dominio;

    @Column(
        name = "altas"
    )
    private String altas;

    @Column(
        name = "bajas"
    )
    private String bajas;

    @OneToMany(
        mappedBy = "compania",
        cascade = CascadeType.ALL,
        fetch = FetchType.LAZY,
        orphanRemoval = true
    )
    private List<Office> office;

...Constructors...
... Getters and Setters...

办公室(儿童)

@Entity()
@Table()
public class Office {
    @Id
    @SequenceGenerator(
        name = "office_sequence",
        sequenceName = "office_sequence",
        allocationSize = 1
    )
    @GeneratedValue(
        strategy = GenerationType.SEQUENCE,
        generator = "office_sequence"
    )
    @Column(
        nullable = false
    )
    @JsonIgnore
    private Long id;

    @Column(
        name = "idRef",
        nullable = false
    )
    private int idRef;

    @Column(
        name = "title",
        nullable = false
    )
    private String title;

    @Column(
        name = "name"
    )
    private String name;
    @Column(
        name = "path"
    )
    private String path;

    @ManyToOne(
        fetch = FetchType.LAZY
    )
    @JoinColumn(
        name = "compania_id",
        referencedColumnName = "id"
    )
    private Compania compania;

    ...Constructors...
    ... Getters and Setters...

我想在我的父对象(具有 OneToMany 关系的对象)中保存或编辑数据 为了实现这一点,我想到了两种方法,但两种方法都有问题。

第一个是将所有内容保存在 Compania(父)类中。像这样,我将 Compania 类的 id 和 JSON 对象作为 Office 对象传递:

public void addOfficeTest(Long companiaId, Office office) {
        // OPTION 1 - Add directly the office to the office list of the Compania Object (parent), then save it using Compania repository
        if (office.getId() != null) {
            office.setId(null);
        }
        Compania companiaFound = companiaRepository.findById(companiaId).get();
        List<Office> listaOffice = companiaFound.getOffice();
        listaOffice.add(office);
        companiaFound.setOffice(listaOffice);
        // method to set references id for user use...
        setIdReferencia(companiaEnc, true, false);
        companiaRepository.save(companiaEnc);

使用这种方法,我的问题是我无法保存我的实体,当我进行 GET 以获取我的 Companias 时,我将 Office 作为一个空字符串。像这样:

{
        "id": 1,
        "name": "Test Compania",
        "dominio": "domain",
        "altas": "OU=nn",
        "bajas": "none",
        "office": []
}

我认为的另一种方法是使用 Office 存储库保存 Office,但是当我尝试获取我的 Compania 时返回了 无限递归错误(因为我将 compania 保存在办公室)...

public void addOfficeTest(Long companiaId, Office office) {
        // OPTION 2 - Save Office with the repository office
        if (office.getId() != null) {
            office.setId(null);
        }
        Compania companiaEnc = companiaRepository.findById(companiaId).get();
        office.setCompania(companiaEnc); // This causes recursion
        officeRepository.save(office); 

所以我被困在这里,因为我不知道如何为我的子对象执行 PUT 或 POST。我不知道我的代码是否有问题或什么。也许它有一个简单的解决方案,但我真的找不到。如果有人可以帮助给我一个如何进行 POST 和 PUT 的示例,我将不胜感激......

谢谢

【问题讨论】:

    标签: java json spring-boot hibernate jpa


    【解决方案1】:

    鉴于您具有双向关系,我认为您缺少在新的 Office 中设置 Compania 对象。大致如下:

    public void addOfficeTest(Long companiaId, Office office) {
        // OPTION 1 - Add directly the office to the office list of the Compania Object (parent), then save it using Compania repository
        if (office.getId() != null) {
            office.setId(null);
        }
        Compania companiaFound = companiaRepository.findById(companiaId).get();
        office.setCompania(companiaFound); // The new line
        List<Office> listaOffice = companiaFound.getOffice();
        listaOffice.add(office);
        companiaFound.setOffice(listaOffice); // You actually don't need this because you've changed the List already
        // method to set references id for user use...
        setIdReferencia(companiaEnc, true, false);
        companiaRepository.save(companiaEnc);
    }
    

    【讨论】:

    • 哦,我不应该使用 officeRepository 来保存 office 对象吗?顺便说一句,你能告诉我一个使用put而不是post的简单方法吗?谢谢!
    • 没有必要主动持久化Office,因为它将通过Compania对象“通过”持久化,因为你有级联配置:@OneToMany(..., cascade = CascadeType.ALL, ...)。这会将 PERSIST、REMOVE、REFRESH、MERGE、DETACH 操作级联到相关实体(在本例中为 Office)。我没有关注你的第二个问题。您需要添加控制器的代码。
    • 您好,我已经尝试过您的 anwser,但是当我尝试获取我的 Companias 时,它给了我无限递归错误
    • 解决此问题的一种方法是将@JsonManagedReference 添加到Compania 中的private List&lt;Office&gt; office; 属性,并将@JsonBackReference 添加到Office 中的private Compania compania; 属性。您可以在这个很棒的在线资源中阅读有关此技术和其他技术以避免无限递归问题的更多信息:baeldung.com/…
    猜你喜欢
    • 2020-09-02
    • 2017-05-30
    • 1970-01-01
    • 2018-07-22
    • 1970-01-01
    • 2021-01-04
    • 2015-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多