gpt4 book ai didi

java - JPA双向OneToMany关系-无法删除子项

转载 作者:太空宇宙 更新时间:2023-11-04 11:48:26 24 4
gpt4 key购买 nike

在双向 OneToMany 关系中,如何在不调用父级拥有的所有子级的情况下删除子级?

由于我的应用程序有点大,我创建了一个示例项目来重现问题。我有 2 个实体,一个父实体和一个子实体。

父级:

package com.example.entity;

import javax.persistence.*;
import java.util.List;

@Entity
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@OneToMany(
mappedBy = "parent",
cascade = CascadeType.ALL,
fetch = FetchType.LAZY,
orphanRemoval = true
)
private List<Child> children;
}

未显示 Getter 和 Setter!

child :

package com.example.entity;

import javax.persistence.*;

@Entity
public class Child {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "parent_id")
private Parent parent;
}

未显示 Getter 和 Setter!

我还有 2 个存储库:

子存储库:

package com.example.dao;

import com.example.entity.Child;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ChildRepository extends JpaRepository<Child, Long> {}

ParentRepsitory: 看起来完全一样。

现在我创建了一个测试来重现该问题:

存储库测试:

package com.example;

import com.example.dao.ChildRepository;
import com.example.dao.ParentRepository;
import com.example.entity.Child;
import com.example.entity.Parent;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.transaction.Transactional;
import java.util.Arrays;

@RunWith(SpringRunner.class)
@SpringBootTest
public class RepositoryTest {
@Autowired
private ChildRepository childRepository;

@Autowired
private ParentRepository parentRepository;

@Test
@Transactional
public void test() {
Parent parent = new Parent();
Child child1 = new Child();
Child child2 = new Child();

parent.setChildren(Arrays.asList(child1, child2));

Assert.assertEquals(0, parentRepository.count());
Assert.assertEquals(0, childRepository.count());

parentRepository.save(parent);

Assert.assertEquals(1, parentRepository.count());
Assert.assertEquals(2, childRepository.count());

childRepository.delete(child1);

Assert.assertEquals(1, parentRepository.count());
Assert.assertEquals(1, childRepository.count());
}
}

但是Child永远不会被删除,计数仍然是2!我读过很多关于或多或少相同问题的问题,答案总是相同的:

parent.getChildren().remove(child1);
parentRepository.save(parent);

这不是办法吗?如果我的 parent 有数千个 child ,我必须从数据库中获取所有 child 才能删除一个?其中最尴尬的事情是,如果实体没有被删除,为什么没有抛出任何错误?那么正确的做法是什么?从父级完全删除列表并始终手动调用子级,这样就没有外键了?从早餐开始我就试图解决这个问题,但我一直在原地踏步。

编辑:添加 hibernate 日志:

Hibernate: select count(*) as col_0_0_ from parent parent0_
Hibernate: select count(*) as col_0_0_ from child child0_
Hibernate: insert into parent (id) values (default)
Hibernate: insert into child (id, parent_id) values (default, ?)
Hibernate: insert into child (id, parent_id) values (default, ?)
Hibernate: select count(*) as col_0_0_ from parent parent0_
Hibernate: select count(*) as col_0_0_ from child child0_
Hibernate: select count(*) as col_0_0_ from parent parent0_
Hibernate: select count(*) as col_0_0_ from child child0_

最佳答案

该子项是分离实例(不是持久对象),如果您调试它,它不应该有它的 id。

我的问题是为什么你创建新对象只是为了删除它?如果您可以在持久化之前确定哪个子项将被删除,为什么不将其从 add(Arrays.asList(child1, child2)) 中排除?

或者,如果您只能在它持久化后才能确定,这意味着您有办法获取该 child1 的持久实例,这样您就可以删除该对象而不会遇到此类问题。

关于java - JPA双向OneToMany关系-无法删除子项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42076764/

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