उद्देश्य:
माता-पिता के बच्चों के लिस्ट में संशोधन करने वाले बच्चों के माता-पिता की सूची में संशोधन सभी बच्चों के लिए प्रचारित होगा और एनएचबीर्नेट को भारी उठाने का काम होगा। माता-पिता संबंध एक आत्म संदर्भ तालिका पर Has-Many
होगा।एनएचबर्ननेट हैस-कैस्केडिंग डिलीट्स के साथ कई संग्रह
समस्या:
अभिभावक (रूट) ऑब्जेक्ट को हटाने का कोई भी प्रयास बच्चे की वस्तुओं को हटाने के अपेक्षित व्यवहार के बजाय अपवाद का कारण बनता है। मैं उपयोग कर रहा हूँ सामान के
संस्करण:
Microsoft SQL सर्वर प्रबंधन स्टूडियो संस्करण 10.0.4064.0
FluentNHibernate संस्करण 1.3
NHibernate संस्करण 3.2.0.4
है वर्तमान वर्ग वस्तुओं और तालिका संरचना मैं के सेट इस व्यवहार को दोहराने के लिए उपयोग कर रहा हूँ।
// Entity
class Task
{
ID { get; set; }
public virtual IList<Task> Children { get; set; }
public virtual byte[] Version { get; protected set; }
public virtual bool IsNew() { return ID <= 0; }
public Task()
{
this.Children = new System.Collections.Generic.List<Task>();
}
// Other properties excluded for brevity
}
// Map
class TaskMap : ClassMap<Task>
{
TaskMap()
{
Table("Task");
Id(x => x.ID, "ID")
.GeneratedBy.HiLo(
"NH_HiLo", "NextHigh", "100",
string.Format("TableName = '{0}'", "Task"));
HasMany<Task>(x => x.Children)
.KeyColumn("ParentTaskID")
.Cascade.AllDeleteOrphan();
// Other properties omitted for brevity
Version(x => x.Version)
.Not.Nullable()
.Generated.Always()
.Column("Version")
.CustomSqlType("timestamp");
}
}
// Repository Delete Method:
public virtual void Delete(Task value)
{
// CurrentSession is an ISession object that is currently open
using (var transaction = CurrentSession.BeginTransaction())
{
try
{
CurrentSession.Delete(value);
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
throw;
}
}
}
// Test Case using NUnit.Framework and FluentNHibernate.Testing:
[TestFixtureSetUp]
public void SetUpFixture()
{
_repository = new Repository();
}
[Test]
public void MappingTest()
{
var task = new Task(); // Omitted assigning other properties for brevity
var entity = new Task(); // Omitted assigning other properties for brevity
entity.Children.Add(task);
_entity = new PersistenceSpecification<Task>(_repository.CurrentSession)
.VerifyTheMappings(entity);
}
[TearDown]
public void TearDown()
{
if (_entity != null && !_entity.IsNew())
{
_repository.Delete(_entity);
_entity = null;
}
}
--Table Script:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Task](
[ID] [bigint] NOT NULL,
[ParentTaskID] [bigint] NULL, -- Notice it DOES HAVE a NULLable FK reference.
[Version] [timestamp] NOT NULL,
CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED(
[ID] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Task] WITH CHECK ADD CONSTRAINT [FK_TasksChild_TasksParent]
FOREIGN KEY([ParentTaskID])
REFERENCES [dbo].[Task] ([ID]) -- Notice the self table reference for child objects
GO
ALTER TABLE [dbo].[Task] CHECK CONSTRAINT [FK_TasksChild_TasksParent]
GO
उपरोक्त तालिका और कक्षाओं के साथ, इन विकल्पों में कैस्केड बदलना और परीक्षण के टियरडाउन के दौरान निर्दिष्ट निष्पादन के साथ, ये परिणाम हैं।
Cascade.AllDeleteOrphan साथ
: रिकर्सिवली उन बच्चों के बच्चों के माध्यम से खुदाई बच्चों में से प्रत्येक के माध्यम से दोहराने के बाद
NHibernate.StaleObjectStateException was unhandled by user code
Message=Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [Task#1015859]
Source=NHibernate
EntityName=Entities.Task
StackTrace:
at NHibernate.Persister.Entity.AbstractEntityPersister.Check(Int32 rows, Object id, Int32 tableNumber, IExpectation expectation, IDbCommand statement) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 2178
at NHibernate.Persister.Entity.AbstractEntityPersister.Delete(Object id, Object version, Int32 j, Object obj, SqlCommandInfo sql, ISessionImplementor session, Object[] loadedState) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 2912
at NHibernate.Persister.Entity.AbstractEntityPersister.Delete(Object id, Object version, Object obj, ISessionImplementor session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 3095
at NHibernate.Action.EntityDeleteAction.Execute() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Action\EntityDeleteAction.cs:line 70
at NHibernate.Engine.ActionQueue.Execute(IExecutable executable) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:line 136
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:line 126
at NHibernate.Engine.ActionQueue.ExecuteActions() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:line 174
at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:line 249
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\DefaultFlushEventListener.cs:line 19
at NHibernate.Impl.SessionImpl.Flush() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1489
at NHibernate.Transaction.AdoTransaction.Commit() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Transaction\AdoTransaction.cs:line 190
at Repositories.Repository.Delete(Task value) in ..\Repositories\Repository.cs:line 22
at TaskTest.TearDown() in ..\Tests\TaskTest.cs:line 76
,:
सीधे शब्दों में बुला पैरेंट ऑब्जेक्ट पर हटाना मैं इस अपवाद और नीचे से प्रत्येक बच्चे को हटाने का प्रयास:
NHibernate.ObjectDeletedException was unhandled by user code
Message=deleted object would be re-saved by cascade (remove deleted object from associations)[Task#1016061]
Source=NHibernate
EntityName=Entities.Task
StackTrace:
at NHibernate.Impl.SessionImpl.ForceFlush(EntityEntry entityEntry) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 914
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\DefaultSaveOrUpdateEventListener.cs:line 140
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\DefaultSaveOrUpdateEventListener.cs:line 76
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\DefaultSaveOrUpdateEventListener.cs:line 53
at NHibernate.Impl.SessionImpl.FireSaveOrUpdate(SaveOrUpdateEvent event) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 2662
at NHibernate.Impl.SessionImpl.SaveOrUpdate(String entityName, Object obj) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 549
at NHibernate.Engine.CascadingAction.SaveUpdateCascadingAction.Cascade(IEventSource session, Object child, String entityName, Object anything, Boolean isCascadeDeleteEnabled) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\CascadingAction.cs:line 249
at NHibernate.Engine.Cascade.CascadeToOne(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\Cascade.cs:line 216
at NHibernate.Engine.Cascade.CascadeAssociation(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\Cascade.cs:line 181
at NHibernate.Engine.Cascade.CascadeProperty(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\Cascade.cs:line 148
at NHibernate.Engine.Cascade.CascadeCollectionElements(Object parent, Object child, CollectionType collectionType, CascadeStyle style, IType elemType, Object anything, Boolean isCascadeDeleteEnabled) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\Cascade.cs:line 240
at NHibernate.Engine.Cascade.CascadeCollection(Object parent, Object child, CascadeStyle style, Object anything, CollectionType type) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\Cascade.cs:line 201
at NHibernate.Engine.Cascade.CascadeAssociation(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\Cascade.cs:line 185
at NHibernate.Engine.Cascade.CascadeProperty(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\Cascade.cs:line 148
at NHibernate.Engine.Cascade.CascadeOn(IEntityPersister persister, Object parent, Object anything) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\Cascade.cs:line 126
at NHibernate.Event.Default.AbstractFlushingEventListener.CascadeOnFlush(IEventSource session, IEntityPersister persister, Object key, Object anything) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:line 207
at NHibernate.Event.Default.AbstractFlushingEventListener.PrepareEntityFlushes(IEventSource session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:line 197
at NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent event) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:line 48
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\DefaultFlushEventListener.cs:line 18
at NHibernate.Impl.SessionImpl.Flush() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1489
at NHibernate.Transaction.AdoTransaction.Commit() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Transaction\AdoTransaction.cs:line 190
at Repositories.Repository.Delete(Task value) in ..\Repositories\Repository.cs:line 22
at Repositories.Repository.Delete(Task value) in ..\Repositories\Repository.cs:line 25
at Repositories.Repository.Delete(Task value) in ..\Repositories\Repository.cs:line 25
at Tests.TaskTest.TearDown() in ..\Tests\TaskTest.cs:line 76
, बच्चों के माध्यम से पुनरावृत्ति बच्चों के अपने सेटों में से प्रत्येक साफ़ करने के बाद, तो बचत/माता-पिता को हटाने मैं इस अपवाद प्राप्त करें: बस पर हटाना बुला
NHibernate.StaleObjectStateException was unhandled by user code
Message=Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [Task#1015960]
Source=NHibernate
EntityName=Entities.Task
StackTrace:
at NHibernate.Persister.Entity.AbstractEntityPersister.Check(Int32 rows, Object id, Int32 tableNumber, IExpectation expectation, IDbCommand statement) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 2178
at NHibernate.Persister.Entity.AbstractEntityPersister.Delete(Object id, Object version, Int32 j, Object obj, SqlCommandInfo sql, ISessionImplementor session, Object[] loadedState) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 2912
at NHibernate.Persister.Entity.AbstractEntityPersister.Delete(Object id, Object version, Object obj, ISessionImplementor session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 3095
at NHibernate.Action.EntityDeleteAction.Execute() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Action\EntityDeleteAction.cs:line 70
at NHibernate.Engine.ActionQueue.Execute(IExecutable executable) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:line 136
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:line 126
at NHibernate.Engine.ActionQueue.ExecuteActions() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:line 174
at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:line 249
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\DefaultFlushEventListener.cs:line 19
at NHibernate.Impl.SessionImpl.Flush() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1489
at NHibernate.Transaction.AdoTransaction.Commit() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Transaction\AdoTransaction.cs:line 190
at Repositories.Repository.Delete(Task value) in ..\Repositories\Repository.cs:line 22
at TaskTest.TearDown() in ..\Tests\TaskTest.cs:line 76
Cascade.All साथ
, बच्चों में से प्रत्येक के माध्यम से पुनरावृत्ति, रिकर्सिवली उन बच्चों के बच्चों के माध्यम से खुदाई और डेले करने का प्रयास करने के बाद
Cascade.AllDeleteOrphan
के समान हैं: पैरेंट ऑब्जेक्ट मैं इस अपवाद प्रत्येक बच्चे को नीचे से ऊपर:
कैस्केड के समान ही।
AllDeleteOrphan, बच्चों के माध्यम से पुनरावृत्ति बच्चों के अपने सेटों में से प्रत्येक साफ़ करने के बाद, तो बचत/माता-पिता को हटाने मैं इस अपवाद:
कोई अपवाद: माता-पिता को सही ढंग से नष्ट कर दिया जाता है लेकिन अब मैं वस्तुओं है कि मुझे नहीं पता अनाथ है चाहते हैं!
मैं कई ब्लॉग/stackoverflow प्रश्न/संसाधन डॉक्स के माध्यम से देखा है और वास्तव में इस मुद्दे का समाधान नहीं देखा है।
यहाँ लिंक मैं पहले से ही के माध्यम से खोदा है की कुछ कर रहे हैं:
- How to delete a referenced object using FluentNHibernate (ye olde "deleted object would be resaved by cascade")
- Error in Cascade : deleted object would be re-saved by cascade
- Setting up Fluent NHibernate one-to-many with cascading deletes using the automapper
- key-many-to-one and key-property association: nhibernate won't DELETE items from set
- https://nhibernate.jira.com/browse/NH-1050
(नोटिस मैं अशक्त FK है) - Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)
(नोटिस मैं टाइमस्टैम्प आशावादी संस्करण का उपयोग करें) ernst_pluess द्वारा - https://forum.hibernate.org/viewtopic.php?t=933496
(टिप्पणी झरना के बारे में = सभी हिलो उपयोग के बारे में एक चेतावनी झंडा फेंक दिया, लेकिन हिलो उत्पन्न या असाइन किया गया है? क्योंकि तकनीकी रूप से NHibernate तो यह उत्पन्न करता है यह प्रदान करती है ...) - Exception deleting child records in NHibernate
(बनाता है यह है कि मैं जो दूर झरना होने के उद्देश्य लेता है !! मैन्युअल रूप से सभी बच्चे वस्तुओं को हटाना होगा,) लगते
कई पदों में रिश्ते को बदलने और सेट करने का उल्लेख किया गया है। इसके विपरीत और बच्चे को रिश्ते बनाने का लक्ष्य पूरी तरह से लक्ष्य नहीं है!
मुझे नहीं पता कि मुझे क्या याद आ रहा है, लेकिन उम्मीद है कि यह ठीक करने के लिए वास्तव में कुछ आसान है जिसे मैं देख रहा हूं। किसी भी प्रकार के मदद की बहुत सराहना की जाएगी!
मैं आपके उत्तर की सराहना करता हूं। यह वही नहीं था जो मैं सुनने की उम्मीद कर रहा था, हालांकि मैं उम्मीद कर रहा था कि मुझे माता-पिता और बच्चे के बीच संबंधों को मैन्युअल रूप से तोड़ना नहीं था, लेकिन ऐसा लगता है कि यह अपरिहार्य है। मुझे एक पैरेंट टास्क संदर्भ जोड़कर पास करने के लिए परीक्षा मिली और टाई को तोड़ने के लिए माता-पिता को शून्य पर सेट करने वाली बाल सूचियों के माध्यम से दोबारा खोदने के लिए हटाने की विधि को ट्विक करना और आखिरकार मूल कार्य को हटा दें, जब कैस्केड.एल्डेलेटेऑर्फन सही तरीके से चालू हो सभी अनाथ कार्यों को हटा देता है। फिर, आपके उत्तर के लिए धन्यवाद। –