Thanks.
However this is still not the behavior I need.
If I replace the person's address with a new one (or set it to null)
there will be an "orphan" record left in the Person table.
Is there a nice way how to delete it? Something like cascade="all-
delete-orphan" which works for collections?
-- as a workaround I implemented IPreUpdateEventListener where I
delete the orphan. But I still hope in a nicer, more declarative,
solution.
var indexForSingleChild =
Array.IndexOf(@event.Persister.PropertyNames, "SingleChild");
if (indexForSingleChild >= 0)
{
var oldChild = @event.OldState[indexForSingleChild] as
SingleChild;
var newChild = @event.State[indexForSingleChild] as SingleChild;
if (oldChild != null && (newChild == null || oldChild.Id !=
newChild.Id))
{
@event.Session.Delete(oldChild);
}
}
Thanks, Stefan
On Jul 7, 1:49 pm, Fabio Maulo <[email protected]> wrote:
> <class name="Person">
> <id name="Id" type="Int32">
> <generator class="hilo" />
> </id>
> <property name="Name" />
> <many-to-one name="Address" unique="true" cascade="all" />
> </class>
> <class name="Address">
> <id name="Id" type="Int32">
> <generator class="hilo" />
> </id>
> <one-to-one name="Person" cascade="all" property-ref="Address" />
> <property name="Street" />
> <property name="CivicNumber" />
> </class>
>
>
>
> On Wed, Jul 7, 2010 at 1:37 AM, xpista <[email protected]> wrote:
> > Could you tell me how should I fix it to make it work?
> > What exactly is wrong?
>
> > Thanks, Stefan
>
> > On Jul 7, 12:36 am, Fabio Maulo <[email protected]> wrote:
> > > Wrong mapping for a bidirectional-one-to-one based on FK
>
> > > On Tue, Jul 6, 2010 at 10:54 AM, xpista <[email protected]> wrote:
> > > > Hi,
>
> > > > I have a problem with updating one-to-one mapped entity.
>
> > > > In first session I create the class with a property which I map one-
> > > > to-one. Cascading is set to "all".
> > > > In second I load the entity and try to _replace_ the property. By
> > > > replace I mean I set it to new instance.
>
> > > > What I expect is that the old instance/record will be deleted and
> > > > the new one inserted.
>
> > > > However what I see is only insert statement (which by subsequent
> > > > load in new session leads to exception:
> > > > NHibernate.HibernateException : More than one row with the given
> > > > identifier was found.)
>
> > > > Is there a way make the one-to-one mapping work as I expect or have
> > > > I misunderstood the whole idea of one-to-one mapping?
>
> > > > Thanks for any pointers, Stefan
>
> > > > --------------
>
> > > > public class Master
> > > > {
> > > > public virtual Guid Id { get; set; }
> > > > public virtual SingleChild SingleChild { get; set; } // one-to-one
> > > > }
>
> > > > public class SingleChild
> > > > {
> > > > public virtual Guid Id { get; set; }
> > > > public virtual Master Master { get; set; } // many-to-one
> > > > }
>
> > > > --------------
>
> > > > <class name="Data.Master, Data" table="MASTER" >
> > > > <id name="Id" column="ID">
> > > > <generator class="guid.comb"/>
> > > > </id>
>
> > > > <one-to-one name="SingleChild" property-ref="Master" cascade="all" /
>
> > > > </class>
>
> > > > <class name="Data.SingleChild, Data" table="SINGLE_CHILD" >
> > > > <id name="Id" column="ID">
> > > > <generator class="guid.comb"/>
> > > > </id>
>
> > > > <many-to-one name="Master" column="FK_MASTER" cascade="all" />
> > > > </class>
>
> > > > --------------
>
> > > > [Test]
> > > > public void VerifyOneToOneUpdate()
> > > > {
> > > > Guid gid;
> > > > // Create
> > > > using (var session = Global.Factory.OpenSession())
> > > > using (var tran = session.BeginTransaction())
> > > > {
> > > > var master = new Master();
> > > > master.SingleChild = new SingleChild {Master = master};
> > > > session.Save(master);
> > > > gid = master.Id;
> > > > tran.Commit();
> > > > }
>
> > > > // Update ??
> > > > using (var session = Global.Factory.OpenSession())
> > > > using (var tran = session.BeginTransaction())
> > > > {
> > > > var p = session.Get<Master>(gid);
> > > > Assert.NotNull(p);
> > > > p.SingleChild = new SingleChild { Master = p };
> > > > session.SaveOrUpdate(p);
> > > > tran.Commit();
> > > > }
>
> > > > // Reload
> > > > using (var session = Global.Factory.OpenSession())
> > > > using (var tran = session.BeginTransaction())
> > > > {
> > > > var p = session.Get<Master>(gid); //
> > > > NHibernate.HibernateException : More than one row with the given
> > > > identifier was found
> > > > Assert.NotNull(p);
> > > > }
> > > > }
>
> > > > --
> > > > You received this message because you are subscribed to the Google
> > Groups
> > > > "nhusers" group.
> > > > To post to this group, send email to [email protected].
> > > > To unsubscribe from this group, send email to
> > > > [email protected]<nhusers%[email protected]>
> > <nhusers%[email protected]<nhusers%[email protected]>
>
> > > > .
> > > > For more options, visit this group at
> > > >http://groups.google.com/group/nhusers?hl=en.
>
> > > --
> > > Fabio Maulo
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "nhusers" group.
> > To post to this group, send email to [email protected].
> > To unsubscribe from this group, send email to
> > [email protected]<nhusers%[email protected]>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/nhusers?hl=en.
>
> --
> Fabio Maulo
--
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en.