2012-05-30 44 views
0

@OneToOne双向关系,其中母公司(P)类有:@OneToOne取代实体

@OneToOne(optional = true, mappedBy = "owner", orphanRemoval = true) 
@Cascade({org.hibernate.annotations.CascadeType.ALL}) 

的getter和子类(C)对消气:

@ForeignKey(name = "fk_reference_owner") 
@MapsId("owner") 
@ManyToOne(fetch = FetchType.LAZY) 
@PrimaryKeyJoinColumns({ 
     @PrimaryKeyJoinColumn(name = "owner_oid", referencedColumnName = "oid"), 
     @PrimaryKeyJoinColumn(name = "owner_id", referencedColumnName = "id") 
}) 

缩写:

P(<it's primary key>)

C(<it's primary key, and it's also FK to P>, <another PK>)

情况是这样的:

我有P(1)C(1, a)坚持数据库 - 和C(1, a)P(1)拥有。现在在代码的某处我创建了P(1)C(1, a)的分离实例。当我打电话给session.merge(p)时,所有属性合并,并在session.commit()后更新。但是,当我将分离对象上的C(1, a)更改为例如C(1, b)时,则不会删除C(1, a),只会保留C(1, b)。我知道这是因为C(1, b)在数据库中不存在,并且休眠没有得到明确的指令来删除C(1, a) - 但它应该可能是自动的,因为@OneToOne。后来因失败@OneToOne关系失败。我知道可能的解决方案之一是在连接的对象上设置P.setC(null)。但对我而言这是不可能的。在合并时,我已经有“更新”分离对象P

在使用自定义tuplizer或类似的东西合并过程中,我可以将child设置为null吗?

你有什么想法如何做到这一点?

回答

0

您有双向关联,但一方声明它为OneToOne,另一方(拥有方)声明它为ManyToOne

如果是OneToOne,它应该是OneToOne的两边。如果它是一个OneTomany,它应该是OneToMany在一边而ManyToOne在另一边。

+0

当我将'ManyToOne'更改为'OneToOne'时我得到了'由于:org.hibernate.MappingException:外键(FKD57C55F9BEABB43A:m_reference [owner_id,owner_oid,target_id,target_oid]))必须具有与引用的主键(m_container [id,oid])' – viliam

+0

如果我把它转换为'OneToOne',就会生成owner_id的唯一键,owner_oid。不能有这样的唯一键,我没有找到一种方法来禁用该唯一键。 – viliam

0

当你在P(1)中拥有的C(1,a)实例不是你创建的实例,而是一个新的实例时,为什么要更改分离的对象? 。也许你想将你对C(1,a)的引用更新为新的持久化引用,并对其进行更改?

+0

不能这样做。更改应用于业务对象,因此我总是获得新的对象状态。比我翻译这个对象到我的映射实体类。这就是为什么它有时发生的情况是先前包含C(1,a)的实例P(1)现在包含C(1,b)。我不知道究竟发生了什么变化,因此我使用session.merge()。 – viliam

相关问题