NHibernate 5.1 ManyToOne - delete orphan not working as expected












1















I have following entities:



public class Person {
public int Id {get;set;}
public String Name {get;set;}
public Passport Passport {get;set;}
}

public class Passport {
public int Id {get;set;}
public String PassportNo {get;set;}
// ... other properties
}


and following mapping (for Person):



ManyToOne(x => x.Passport, m =>
{
m.Column("PassportId");
m.Lazy(LazyRelation.NoLazy);
m.Unique(true);
m.Cascade(Cascade.All | Cascade.DeleteOrphans);
});


DB schema:



Table Person:

Id | Name | PassportId

Table Passport:

Id | PassportNo | other props.


As we can see, Person has it's passport, but passport has no idea about its owner, which is behaviour I want. There are 2 more assumptions:





  • Person can have only 1 passport at a time


  • Passport can NOT exists without person


Problem is, when I assign new Passport to a Person, the old Passport remains in DB.



person.Passport = new Passport() { PassportNo = "AB 123456" };
// ...
session.Flush();
session.Commit();


SQL queries that are generated are INSERT and UPDATE (inserts new Passport, and updates Person with new Passport) - however there is no DELETE on orphaned, old passport.



The workaround I found is to set current Passport to null, call session.Flush(), and assign new Passport, like this:



person.Passport = null;
session.Flush();
person.Passport = new Passport() { PassportNo = "AB 123456" };
// ...
session.Flush();
session.Commit();


however IMO it is a hacky solution.



So, summing it up:




  • am I missing something in my mapping?

  • is above behaviour a bug in NH?

  • can it be solved without hacky Flush()?










share|improve this question























  • Are the cascade settings correct? I found this (notherdev.blogspot.com/2012/01/mapping-by-code-manytoone.html) and it looks like Remove is an option rather than DeleteOrphan.

    – David Osborne
    Nov 16 '18 at 8:58
















1















I have following entities:



public class Person {
public int Id {get;set;}
public String Name {get;set;}
public Passport Passport {get;set;}
}

public class Passport {
public int Id {get;set;}
public String PassportNo {get;set;}
// ... other properties
}


and following mapping (for Person):



ManyToOne(x => x.Passport, m =>
{
m.Column("PassportId");
m.Lazy(LazyRelation.NoLazy);
m.Unique(true);
m.Cascade(Cascade.All | Cascade.DeleteOrphans);
});


DB schema:



Table Person:

Id | Name | PassportId

Table Passport:

Id | PassportNo | other props.


As we can see, Person has it's passport, but passport has no idea about its owner, which is behaviour I want. There are 2 more assumptions:





  • Person can have only 1 passport at a time


  • Passport can NOT exists without person


Problem is, when I assign new Passport to a Person, the old Passport remains in DB.



person.Passport = new Passport() { PassportNo = "AB 123456" };
// ...
session.Flush();
session.Commit();


SQL queries that are generated are INSERT and UPDATE (inserts new Passport, and updates Person with new Passport) - however there is no DELETE on orphaned, old passport.



The workaround I found is to set current Passport to null, call session.Flush(), and assign new Passport, like this:



person.Passport = null;
session.Flush();
person.Passport = new Passport() { PassportNo = "AB 123456" };
// ...
session.Flush();
session.Commit();


however IMO it is a hacky solution.



So, summing it up:




  • am I missing something in my mapping?

  • is above behaviour a bug in NH?

  • can it be solved without hacky Flush()?










share|improve this question























  • Are the cascade settings correct? I found this (notherdev.blogspot.com/2012/01/mapping-by-code-manytoone.html) and it looks like Remove is an option rather than DeleteOrphan.

    – David Osborne
    Nov 16 '18 at 8:58














1












1








1








I have following entities:



public class Person {
public int Id {get;set;}
public String Name {get;set;}
public Passport Passport {get;set;}
}

public class Passport {
public int Id {get;set;}
public String PassportNo {get;set;}
// ... other properties
}


and following mapping (for Person):



ManyToOne(x => x.Passport, m =>
{
m.Column("PassportId");
m.Lazy(LazyRelation.NoLazy);
m.Unique(true);
m.Cascade(Cascade.All | Cascade.DeleteOrphans);
});


DB schema:



Table Person:

Id | Name | PassportId

Table Passport:

Id | PassportNo | other props.


As we can see, Person has it's passport, but passport has no idea about its owner, which is behaviour I want. There are 2 more assumptions:





  • Person can have only 1 passport at a time


  • Passport can NOT exists without person


Problem is, when I assign new Passport to a Person, the old Passport remains in DB.



person.Passport = new Passport() { PassportNo = "AB 123456" };
// ...
session.Flush();
session.Commit();


SQL queries that are generated are INSERT and UPDATE (inserts new Passport, and updates Person with new Passport) - however there is no DELETE on orphaned, old passport.



The workaround I found is to set current Passport to null, call session.Flush(), and assign new Passport, like this:



person.Passport = null;
session.Flush();
person.Passport = new Passport() { PassportNo = "AB 123456" };
// ...
session.Flush();
session.Commit();


however IMO it is a hacky solution.



So, summing it up:




  • am I missing something in my mapping?

  • is above behaviour a bug in NH?

  • can it be solved without hacky Flush()?










share|improve this question














I have following entities:



public class Person {
public int Id {get;set;}
public String Name {get;set;}
public Passport Passport {get;set;}
}

public class Passport {
public int Id {get;set;}
public String PassportNo {get;set;}
// ... other properties
}


and following mapping (for Person):



ManyToOne(x => x.Passport, m =>
{
m.Column("PassportId");
m.Lazy(LazyRelation.NoLazy);
m.Unique(true);
m.Cascade(Cascade.All | Cascade.DeleteOrphans);
});


DB schema:



Table Person:

Id | Name | PassportId

Table Passport:

Id | PassportNo | other props.


As we can see, Person has it's passport, but passport has no idea about its owner, which is behaviour I want. There are 2 more assumptions:





  • Person can have only 1 passport at a time


  • Passport can NOT exists without person


Problem is, when I assign new Passport to a Person, the old Passport remains in DB.



person.Passport = new Passport() { PassportNo = "AB 123456" };
// ...
session.Flush();
session.Commit();


SQL queries that are generated are INSERT and UPDATE (inserts new Passport, and updates Person with new Passport) - however there is no DELETE on orphaned, old passport.



The workaround I found is to set current Passport to null, call session.Flush(), and assign new Passport, like this:



person.Passport = null;
session.Flush();
person.Passport = new Passport() { PassportNo = "AB 123456" };
// ...
session.Flush();
session.Commit();


however IMO it is a hacky solution.



So, summing it up:




  • am I missing something in my mapping?

  • is above behaviour a bug in NH?

  • can it be solved without hacky Flush()?







nhibernate many-to-one mapping-by-code






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 13 '18 at 13:53









JohnnyBzzJohnnyBzz

148213




148213













  • Are the cascade settings correct? I found this (notherdev.blogspot.com/2012/01/mapping-by-code-manytoone.html) and it looks like Remove is an option rather than DeleteOrphan.

    – David Osborne
    Nov 16 '18 at 8:58



















  • Are the cascade settings correct? I found this (notherdev.blogspot.com/2012/01/mapping-by-code-manytoone.html) and it looks like Remove is an option rather than DeleteOrphan.

    – David Osborne
    Nov 16 '18 at 8:58

















Are the cascade settings correct? I found this (notherdev.blogspot.com/2012/01/mapping-by-code-manytoone.html) and it looks like Remove is an option rather than DeleteOrphan.

– David Osborne
Nov 16 '18 at 8:58





Are the cascade settings correct? I found this (notherdev.blogspot.com/2012/01/mapping-by-code-manytoone.html) and it looks like Remove is an option rather than DeleteOrphan.

– David Osborne
Nov 16 '18 at 8:58












1 Answer
1






active

oldest

votes


















0














After long searching for solution, I found that there is a Join mapping, which perfectly fits above scenario.



Hope it helps someone.



More info here:
http://notherdev.blogspot.com/2012/01/mapping-by-code-join.html






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53282564%2fnhibernate-5-1-manytoone-delete-orphan-not-working-as-expected%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    After long searching for solution, I found that there is a Join mapping, which perfectly fits above scenario.



    Hope it helps someone.



    More info here:
    http://notherdev.blogspot.com/2012/01/mapping-by-code-join.html






    share|improve this answer




























      0














      After long searching for solution, I found that there is a Join mapping, which perfectly fits above scenario.



      Hope it helps someone.



      More info here:
      http://notherdev.blogspot.com/2012/01/mapping-by-code-join.html






      share|improve this answer


























        0












        0








        0







        After long searching for solution, I found that there is a Join mapping, which perfectly fits above scenario.



        Hope it helps someone.



        More info here:
        http://notherdev.blogspot.com/2012/01/mapping-by-code-join.html






        share|improve this answer













        After long searching for solution, I found that there is a Join mapping, which perfectly fits above scenario.



        Hope it helps someone.



        More info here:
        http://notherdev.blogspot.com/2012/01/mapping-by-code-join.html







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 28 '18 at 9:48









        JohnnyBzzJohnnyBzz

        148213




        148213






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53282564%2fnhibernate-5-1-manytoone-delete-orphan-not-working-as-expected%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Full-time equivalent

            Bicuculline

            さくらももこ