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:
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
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:
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
Are the cascade settings correct? I found this (notherdev.blogspot.com/2012/01/mapping-by-code-manytoone.html) and it looks likeRemove
is 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:
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
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
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 likeRemove
is 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 likeRemove
is 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
Remove
is an option rather thanDeleteOrphan
.– David Osborne
Nov 16 '18 at 8:58