NHibernate 一对多映射有时不保存 children
NHibernate one to many mapping not saving children only sometimes
仅通过 nhibernate 保存 parent object 的 child 有时会导致不在 table 中插入 child。
这在大多数情况下都有效,并且在数千次中只有几次 child 丢失了。
这是一个大型 multi-threaded 应用程序。
以下是 child 映射:
<class name="Child" table="children" lazy="false" optimistic-lock="all" dynamic-update="true">
<id name="Id" column="id">
<generator class="native" />
</id>
<many-to-one name="MyParent" class="Parent" column="parent_id" not-null="true"/>
...
...
和 Child Class :
public class Child
{
public long Id { get; set; }
public Parent MyParent { get; set; }
...
..
Parent映射:
<id name="Id" column="id">
<generator class="native" />
</id>
<set name="Children" table="children" cascade="none" lazy="true" inverse="true">
<key column="parent_id" not-null="true" />
<one-to-many class="Child" />
</set>
...
...
下面是ParentClass
public class Parent
{
public long Id { get; set; }
public ICollection<Child> Children { get; set; }
...
...
..
}
添加 parent 和 child 的代码如下所示:
var theParent = new Parent
{
...
}
...
// start the transaction if not begun by the caller
// a few lines later...
Session.Save(theParent);
// Commit transaction only if this method began the transaction...
...
var child = new Child
{
MyParent = theParent,
...
...
}
...
// start the transaction if not begun by the caller
// a few lines later...
Session.Save(child);
// Commit transaction only if this method began the transaction...
// make sure the two-way associations are updated!
if (!child.MyParent.Children.Contains(child))
child.MyParent.Children.Add(child);
...
检查调用者是否已开始事务的机制似乎没有任何错误,并且调用者不会在不抛出异常并记录异常的情况下回滚。我没有发现任何交易被回滚的痕迹。
- Parent映射中的"cascade"选项有问题吗?
- 是否因为事务提交发生在 parent 集合中添加 child 之前?
无论哪种情况,为什么 child 仅在少数情况下丢失。这很难处理,并且可能会悄悄地在生产中引起很多问题。发生这种情况的原因可能是什么?
- 没有
- 没有
我敢打赌你的交易处理机制有缺陷,有时交易根本没有提交。它最终收集垃圾,导致它被无声地处理和回滚。如果会话 Close
发生在事务提交之前,也会发生这种情况。
您可以通过记录事务 starts/commits/rollbacks 和相关的上下文信息来跟踪它,以匹配开始与提交和回滚。
这可能非常棘手。什么是相关上下文信息?这在很大程度上取决于应用程序类型。在 IIS 下的 Web 应用程序中,线程上下文不好,调用上下文不好。如果在负载下发生 asp.net 线程敏捷性切换,它们都会丢失。大多数情况下只保留 HTTP 上下文。 (并注意 async await
为 运行 配置了 "callback" 而没有任何上下文...)
仅通过 nhibernate 保存 parent object 的 child 有时会导致不在 table 中插入 child。 这在大多数情况下都有效,并且在数千次中只有几次 child 丢失了。
这是一个大型 multi-threaded 应用程序。
以下是 child 映射:
<class name="Child" table="children" lazy="false" optimistic-lock="all" dynamic-update="true">
<id name="Id" column="id">
<generator class="native" />
</id>
<many-to-one name="MyParent" class="Parent" column="parent_id" not-null="true"/>
...
...
和 Child Class :
public class Child
{
public long Id { get; set; }
public Parent MyParent { get; set; }
...
..
Parent映射:
<id name="Id" column="id">
<generator class="native" />
</id>
<set name="Children" table="children" cascade="none" lazy="true" inverse="true">
<key column="parent_id" not-null="true" />
<one-to-many class="Child" />
</set>
...
...
下面是ParentClass
public class Parent
{
public long Id { get; set; }
public ICollection<Child> Children { get; set; }
...
...
..
}
添加 parent 和 child 的代码如下所示:
var theParent = new Parent
{
...
}
...
// start the transaction if not begun by the caller
// a few lines later...
Session.Save(theParent);
// Commit transaction only if this method began the transaction...
...
var child = new Child
{
MyParent = theParent,
...
...
}
...
// start the transaction if not begun by the caller
// a few lines later...
Session.Save(child);
// Commit transaction only if this method began the transaction...
// make sure the two-way associations are updated!
if (!child.MyParent.Children.Contains(child))
child.MyParent.Children.Add(child);
...
检查调用者是否已开始事务的机制似乎没有任何错误,并且调用者不会在不抛出异常并记录异常的情况下回滚。我没有发现任何交易被回滚的痕迹。
- Parent映射中的"cascade"选项有问题吗?
- 是否因为事务提交发生在 parent 集合中添加 child 之前?
无论哪种情况,为什么 child 仅在少数情况下丢失。这很难处理,并且可能会悄悄地在生产中引起很多问题。发生这种情况的原因可能是什么?
- 没有
- 没有
我敢打赌你的交易处理机制有缺陷,有时交易根本没有提交。它最终收集垃圾,导致它被无声地处理和回滚。如果会话 Close
发生在事务提交之前,也会发生这种情况。
您可以通过记录事务 starts/commits/rollbacks 和相关的上下文信息来跟踪它,以匹配开始与提交和回滚。
这可能非常棘手。什么是相关上下文信息?这在很大程度上取决于应用程序类型。在 IIS 下的 Web 应用程序中,线程上下文不好,调用上下文不好。如果在负载下发生 asp.net 线程敏捷性切换,它们都会丢失。大多数情况下只保留 HTTP 上下文。 (并注意 async await
为 运行 配置了 "callback" 而没有任何上下文...)