代码之家  ›  专栏  ›  技术社区  ›  Tom

删除一对一关系

  •  2
  • Tom  · 技术社区  · 16 年前

    我上这些课。

    @Entity
    @Table(name ="a")
    class A{
      private Integer aId;
      private B b;
    
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      @Column(name = "id_a")
      public Integer getAId() {
    return aId;
      }
    
      @OneToOne(mappedBy = "a", cascade={CascadeType.ALL})
      public B getB() {
            return b;
        }
    }
    
    @Entity
    @Table (name= "b")
    class B{
        private A a;
    
        @OneToOne
        @JoinColumn(name = "id_a")
        public A getA() {
            return a;
        }
    
    }
    

    桌子看起来像:

    a)ID_U A其他字段…。|

    b)id_b fk_id_u a其他字段..|

    但是,当我尝试删除的一个实例时,

    org.hibernate.objectDeletedException(删除异常): 删除的对象将由重新保存 级联: (从关联中删除已删除的对象)[B 130]

    我尝试在交叉引用中设置空值:

    b.setA(null) 
    a.setB(null)
    

    但异常仍然会被抛出。

    我所做的就是删除a中的一行,并将b的外键留空,但是当我再次尝试删除b时,会得到相同的错误。

    这是我的删除代码:

    public static void delete(Object object) throws Exception {
            Transaction tx = getSession().beginTransaction();       
            try {
                getSession().delete(object);
                tx.commit();
            } catch (Exception ex) {
                tx.rollback();
                getSession().close();
                throw ex;
            }
        }
    

    getSession 始终返回有效会话。

    我有什么东西不见了吗?

    2 回复  |  直到 11 年前
        1
  •  1
  •   Serge    16 年前

    从顶部开始,继续向下工作。您需要删除表B中对A的引用。因此,请在A中查找要删除的记录的B中的引用,并在B中删除该记录。然后返回A并在A中删除该记录。

    如果您使用的是SQL Server,那么可以在表A上设置级联删除,这将自动完成。不过你得小心点。对于复杂的结构,我不推荐这样做。

        2
  •  0
  •   jwaddell    16 年前

    您是否在单独的交易中取消交叉引用?可能需要提交这些更改才能使删除生效。