当前位置: 首页 > 知识库问答 >
问题:

Spring boot JPA:在多对一关系中删除父实体时,如何保留子实体?

锺英卫
2023-03-14

我是Spring BootJPA的新手,正在努力找出多个实体之间的关系。

我有一个用户实体、一个产品实体和一个评论实体。一个用户有很多评论。一个产品有很多评论。评论有一个产品和一个用户。

目前,我正在为用户使用一对多的关系

我的问题:

  1. 如何在不删除产品实体和用户实体的情况下删除审阅实体?
  2. 我应该使用哪种级联类型?

用户实体:

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "user_name")
    private String userName;
    @Column(name = "email")
    private String email;
    @Column(name = "password")
    private String password;


    @JsonManagedReference("reviews")
    @JsonIgnore
    @OneToMany(fetch = FetchType.LAZY,
            mappedBy = "user")
    private List<Review> reviews = new ArrayList<>();
//constructor + getter+ setter

产品实体:

@Entity
@Table(name = "products")
public class Product {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private Float price;
    @Transient
    private Float rate;

    private String category;
    private String brand;


    @JsonManagedReference("reviews")
    @JsonIgnore
    @OneToMany(mappedBy = "product")
    List<Review> reviews = new ArrayList<>();
//constructor + getter+ setter

审查实体:

@Entity
@Table(name = "reviews")
public class Review {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Float rate;
    private String comment;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id",referencedColumnName = "id")
    @JsonBackReference("user")
    private User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JsonBackReference("product")
    @JoinColumn(name = "product_id",referencedColumnName = "id")
    private Product product;
//constructor + getter+ setter

用户控制器:

@CrossOrigin(origins = "http://localhost:3000")
@RestController
@RequestMapping(path="users/")
public class UserController {

    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    ...
    @DeleteMapping("{userid}")
    public User deleteUser(@PathVariable("userid") Long userid){
        return userService.deleteById(userid);
    }
}

用户服务:

@Service
public class UserService {
    private final UserRepository userRepository;
    private final ReviewRepository reviewRepository;
    //dependency injection
    @Autowired
    public UserService(UserRepository userRepository, ReviewRepository reviewRepository) {
        this.userRepository = userRepository;
        this.reviewRepository =reviewRepository;
    }

   ...
    public User getUserById(Long id){
        return userRepository.findById(id).orElseThrow(()->
                new UserNotFoundException(id));
    }
    public User deleteById(Long id){
        User user = getUserById(id);
        userRepository.delete(user);
        return user;
    }

}

简单运行:

@SpringBootApplication
public class GroceryShoppingAppApplication  {

    public static void main(String[] args) {
        ConfigurableApplicationContext configurableApplicationContext =
                SpringApplication.run(GroceryShoppingAppApplication.class, args);

        UserRepository userRepository = configurableApplicationContext.getBean(UserRepository.class);
        ProductRepository productRepository =configurableApplicationContext.getBean(ProductRepository.class);
        ReviewRepository reviewRepository = configurableApplicationContext.getBean(ReviewRepository.class);

        User debbi= new User("Debbi","debbi@gamil.com","password");

        Product apple = new Product("Apple",(float)3.40,"Fruit","Gala");
        Product milk = new Product("Milk",(float)5.22,"Dairy","Anchor");

        Review review1 = new Review(debbi,(float)4.5,"Good taste",apple);
        Review review2 = new Review(debbi,(float)5.0,"Good milk",milk);

        productRepository.save(apple);
        productRepository.save(milk);

        userRepository.save(debbi);

        reviewRepository.save(review1);
        reviewRepository.save(review2);

我认为我不应该使用casacadeType。所有这些都是因为当删除用户时,我不应该删除评论中的产品。我尝试了其他类型,错误仍然存在。因此,目前我没有使用任何casacadeType,需要逐个保存每个实体。

请帮我做这件事。

共有1个答案

苏健柏
2023-03-14

您会收到错误,因为审阅模型中的用户没有引用的列值。

请尝试以下代码:

@JoinCol列(name="user_id",引用的列名="id")

 类似资料:
  • 删除父实体时,我还想删除关联的子实体(从数据库中)。我试图在删除时使用级联,如下所示,但我一定做错了什么。 当对父实体对象调用删除时,我收到错误消息:“该实体仍在数据库的其他地方引用”。我可以确认该实体在数据库的其他地方引用的唯一地方是在下面的两个表中(如果我手动从数据库中删除子行,对父实体对象的删除调用工作正常)。在过去的9个小时里,我一直在阅读实体对象并尝试不同的东西。我做错了什么? 这是我的

  • 我的实体更新有问题。如你所见,我有三个实体。 包含类中的列表。 包含类中的列表。 从我的SQL语句中可以看到,字段和是唯一的。我的表中只允许该组合的一行。 当我用类的新列表更新父实体()时,我希望Hibernate删除旧列表本身并创建新实体。一个一个地更新孩子是有点困难的。这就是为什么我要直接删除所有相关的孩子。 当我更新并为其提供包含具有唯一名称的和(数据库中已存在的实体)组合的列表时,我会出现

  • 我在删除子实体项目时遇到问题。每次我删除它的时候,什么都没有发生,父节点和子节点之间的关联仍然存在。我在网上搜索过,有些人建议使用orphanremoval,但我试过了,没有用。如果任何人可以建议,不胜感激。我的代码如下: 资产实体 (CHILD) 是单向关系,因此资产实体不包含任何@ManyToOne 在我的 SQL 数据库表中,我的关系CLIENTPROFILE_CLIENTASSET,它们通

  • 我知道你需要保持有关系的实体同步,也就是说,当你从一个父实体中移除一个子实体时,你也应该在子实体中将父实体的属性设置为空。在我的示例中,我有以下父实体: 孩子: 从父级中删除子级的代码如下(在此示例中,可以多次在其列表中具有相同的): 我首先将每个子级的<code>Parent</code>设置为NULL,然后将它们从集合中删除。这将使实体保持同步。我还可以将代码更改为以下内容: 当然,在这种情况

  • 我的两个实体有一对一的关系 我尝试通过此方法删除我的用户实体 PasswordResetTokenRepository类,我在服务方法中调用了该类,用于删除用户,我使用了常规Hibernate方法deleteById(Long id) 但是当我尝试通过此方法删除时,出现此错误:not-null 属性引用 null 或瞬态值:kpi.diploma.ovcharenko.entity.user.Pa

  • 我的实体。ValidationStep与documentDetail有一对一的关系,documentDetail与documentValidations有一个完全的关系 我的删除查询 父ValidationStep被删除,但是docDetail和documentValidations仍然在数据库中。