NHibernate 5.1 ManyToOne - delete orphan not working as expected
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:
Personcan have only 1 passport at a time
Passportcan 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
add a comment |
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:
Personcan have only 1 passport at a time
Passportcan 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
Are the cascade settings correct? I found this (notherdev.blogspot.com/2012/01/mapping-by-code-manytoone.html) and it looks likeRemoveis an option rather thanDeleteOrphan.
– David Osborne
Nov 16 '18 at 8:58
add a comment |
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:
Personcan have only 1 passport at a time
Passportcan 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
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:
Personcan have only 1 passport at a time
Passportcan 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
nhibernate many-to-one mapping-by-code
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 likeRemoveis an option rather thanDeleteOrphan.
– David Osborne
Nov 16 '18 at 8:58
add a comment |
Are the cascade settings correct? I found this (notherdev.blogspot.com/2012/01/mapping-by-code-manytoone.html) and it looks likeRemoveis an option rather thanDeleteOrphan.
– 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
add a comment |
1 Answer
1
active
oldest
votes
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
add a comment |
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
add a comment |
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
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
answered Nov 28 '18 at 9:48
JohnnyBzzJohnnyBzz
148213
148213
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
Are the cascade settings correct? I found this (notherdev.blogspot.com/2012/01/mapping-by-code-manytoone.html) and it looks like
Removeis an option rather thanDeleteOrphan.– David Osborne
Nov 16 '18 at 8:58