0

I have @OneToOne bidirectional relationship where parent (P) class has:

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

on getter and child class (C) has on getter:

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

Abbreviations:

P(<it's primary key>)

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

Situation looks like this:

I have P(1) and C(1, a) persisted in database - and C(1, a) is owned by P(1). Now somewhere in code I create detached instances of P(1) and C(1, a). When I call session.merge(p) then all properties are merged and after session.commit() they are updated. But when I change C(1, a) on detached object to for example C(1, b) then C(1, a) is not deleted, only C(1, b) is persisted. I know it's because that C(1, b) doesn't exist in database and hibernate didn't get clear instruction to delete C(1, a) - but it should be probably automatic because of @OneToOne. Later it fails because of broken @OneToOne relationship. I know one of possible solutions is set P.setC(null) on attached object. But it's not possible in my case. In time of merging I already have "updated" detached object P.

Can I set child to null somewhere during merging with use of custom tuplizer or something like that?

Do you have any ideas how this could be done?

viliam
  • 503
  • 6
  • 23

2 Answers2

0

You have a bidirectional association, but one side declares it as a OneToOne, and the other side (the owning side) declares it as a ManyToOne.

If it's a OneToOne, it should be OneToOne on both sides. If it's a OneTomany, it should be OneToMany on one side and ManyToOne on the other side.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • when I change `ManyToOne` to `OneToOne` I get `Caused by: org.hibernate.MappingException: Foreign key (FKD57C55F9BEABB43A:m_reference [owner_id,owner_oid,target_id,target_oid])) must have same number of columns as the referenced primary key (m_container [id,oid])` – viliam May 30 '12 at 19:20
  • If I chage it to `OneToOne` an unique key for owner_id,owner_oid is generated. Can't have unique key like that and I didn't find a way to disable that unique key. – viliam May 30 '12 at 20:31
0

Why exactly do you want to change the detached object, when the instance of C(1, a) you have in P(1) is not the one you've created, but a new one, from the persistent context. Perhaps you want to update your reference to C(1, a) to the new, persisted one, and make your changes on it?

Denis Tulskiy
  • 19,012
  • 6
  • 50
  • 68
  • can't do that. Changes are applied on business objects, therefore I always get new state of object. Than I translate this object to my mapped entity classes. That's why it sometimes happen that instance P(1) which previously contained C(1,a) now contains C(1,b). I don't know what exactly changed and therefore I use session.merge(). – viliam May 30 '12 at 19:19