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

双向@OneToMany/@ManyToOne关系级联

郎建章
2023-03-14

我在将带有@ManyToOne关系的实体(雇员)映射到带有@OneToMany关系的实体(社区)时遇到了问题。

当我将一个实体(社区)分配给一个实体(员工),其中社区的值为空时,它工作正常。

问题出现了,如果雇员已经为社区分配了价值。当我更改该值并保存更改时,该员工为社区获得了新的值,并且这个新社区在集合中获得了该员工。唯一的问题是,老社区仍然有这个员工在收集,但它应该被删除。这只有在数据库重新启动时才会发生。

我试图使用@JoinCol列和@JoinTable来解决这个问题,但问题是一样的。我想通过在更新/创建服务方法中调用JPA来避免从旧关系中删除实体。

这个问题有什么解决办法吗?

以下是代码:

>

  • 一个社区

     @Entity
     @Table(name = "community")
     public class Community implements Serializable {
    
     private static final long serialVersionUID = 1L;
    
     @Id
     @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
     @SequenceGenerator(name = "sequenceGenerator")
     @Column(name = "id")
     private Long id;
    
     @OneToMany(mappedBy = "community", orphanRemoval = true, cascade = CascadeType.ALL)
     private Set<Employee> employees = new java.util.LinkedHashSet<>();
    
     public Long getId() {
         return this.id;
     }
    
     public Community id(Long id) {
         this.setId(id);
         return this;
     }
    
     public void setId(Long id) {
         this.id = id;
     }
    
     public Set<Employee> getEmployees() {
         return this.employees;
     }
    
     public void setEmployees(Set<Employee> employees) {
         if (this.employees != null) {
             this.employees.forEach(i -> i.setCommunity(null));
         }
         if (employees != null) {
             employees.forEach(i -> i.setCommunity(this));
         }
         this.employees = employees;
     }
    
     public Community employees(Set<Employee> employees) {
         this.setEmployees(employees);
         return this;
     }
    
     public Community addEmployees(Employee employee) {
         this.employees.add(employee);
         employee.setCommunity(this);
         return this;
     }
    
     public Community removeEmployees(Employee employee) {
         this.employees.remove(employee);
         employee.setCommunity(null);
         return this;
     }
    

    一个雇员。

      @Entity
      @Table(name = "employee")
      public class Employee implements Serializable {
    
      private static final long serialVersionUID = 1L;
    
      @Id
      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
      @SequenceGenerator(name = "sequenceGenerator")
      @Column(name = "id")
      private Long id;
    
      @ManyToOne(optional = false)
      @JoinColumn(name = "community_id")
      //    @JoinTable(name = "rel_community__employees",
      //        joinColumns = {@JoinColumn(name = "community_id", referencedColumnName = 
                "id", nullable = false)},
      //        inverseJoinColumns = {@JoinColumn(name = "employee_id", 
                referencedColumnName = "id", nullable = false)})
      @Cascade({CascadeType.PERSIST, CascadeType.REFRESH)
      private Community community;
    
      public Long getId() {
          return this.id;
      }
    
      public Employee id(Long id) {
          this.setId(id);
          return this;
      }
    
      public void setId(Long id) {
          this.id = id;
      }
    
      public Community getCommunity() {
          return this.community;
      }
    
      public void setCommunity(Community community) {
          this.community = community;
      }
    
      public Employee community(Community community) {
          this.setCommunity(community);
          return this;
      }
    

    管理{@link Employee}的服务实现。

      @Service
      @Transactional
      public class EmployeeServiceImpl implements EmployeeService {
    
      @Override
      public EmployeeDTO save(EmployeeDTO employeeDTO) {
          Employee employee = employeeMapper.toEntity(employeeDTO);
          employee = employeeRepository.save(employee);
          return employeeMapper.toDto(employee);
      }
    
      @Override
      public EmployeeDTO update(EmployeeDTO employeeDTO) {
          Employee employee = employeeMapper.toEntity(employeeDTO);
          employee = employeeRepository.save(employee);
          return employeeMapper.toDto(employee);
      }
    

    }

  • 共有1个答案

    公良子轩
    2023-03-14

    这仅在数据库重新启动时发生。

    您是否确定一个社区集合中的员工与另一个社区中的员工相同(即具有相同的id)?我猜您可能有重复的Employee对象。

    你的代码在我看来很好,所以这应该像你预期的那样工作。

    如果没有重复的< code>Employee行,另一种可能的解释是您之前的更新没有正确提交到数据库(您的数据库丢失了数据)。< code>Employee对< code>Community集合的成员资格是通过表< code>employee中的FK community_id定义的,因此,如果您在< code>Community的集合中发现一个不属于它的< code>Employee,这意味着FK值没有正确更新,或者更新它的事务没有正确提交。

    所以,现在你必须弄清楚那里到底发生了什么。我的猜测是,由于某些原因,FK没有正确更新。

     类似资料:
    • 问题内容: 假设我有两个实体: 然后,我要保留“客户”实体,然后,参照先前添加的“客户”保留“订单”实体。当我从数据库中检索此客户并调用getOrders时,它将返回空集。这是正常行为吗?如果是,当我添加新的Order实体时,我该怎么做以自动刷新此集合? 问题答案: Jpa不会为您维护关系,因此应用程序需要设置双向关系的两端,以使它们与数据库保持同步。当您设置了order-> customer关系

    • 拥有2个实体:订单和产品。1个订单可以有多个产品,多个产品可以属于1个订单(每个产品只属于1个订单)。 尝试了@JsonIgnore。这不会返回子元素或父元素。尝试了@JsonManagedReference和@JsonBackReference-仍然没有成功。 请给我指点一下

    • 问题内容: 在JPA注释参考的示例部分中: 示例1-59 @OneToMany-具有泛型的客户类 示例1-60 @ManyToOne-具有泛型的Order类 在我看来,实体是协会的所有者。但是,在同一文档中对属性的说明中写道: 如果关系是双向的,则将关联的反(非所有权)侧的maptedBy元素设置为拥有该关系的字段或属性的名称,如示例1-60所示。 但是,如果我没有记错,则在示例中看起来,实际上是

    • 我正在尝试在 /addNewUser 终结点上使用以下 POST 请求创建新用户:- 发布请求 UserController类:- 用户服务类:- 用户存储库界面 但我得到了以下例外:- 用户模型类 AuthoritiesModel类:- 最初,我认为我的post请求或Jackson API的反序列化存在一些问题,所以我打印了控制器方法中UserModel字段的值,并且所有值都设置正确,包括Aut

    • 环境:Spring 4.0.3,spring-data-jpa 1.2.0,Hibernate 4.2.10,jackson 2.3.3,lombok 1.12.6, 科目实体(已编辑) 用户实体(已编辑) 事务管理器(编辑)

    • 我正在寻找如何删除关系的寄存器一对多/多对一。问题是当我执行EntityManager.remove()时,所有记录都被删除,我希望删除唯一的孩子(DiasTurma)而不是您的父级(Turma)。 我是这样尝试的 方法