NHibernate一对多映射有时只能保存孩子

时间:2016-03-29 12:41:50

标签: c# .net nhibernate orm one-to-many

仅通过nhibernate保存父对象的子对象有时会导致不将子对象插入表中。 这种情况大部分时间都有效,而且只有成千上万次,孩子失踪了。

这是一个大型多线程应用程序。

以下是子映射:

<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"/>
...
...

和儿童班:

public class Child
{
    public long Id { get; set; }
    public Parent MyParent { get; set; }
...
..

父映射:     

<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>
...
...

以下是父类

public class Parent
{
    public long Id { get; set; }
    public ICollection<Child> Children { get; set; }
...
...
..
}

添加父母和孩子的代码如下所示:

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);
...

检查调用者是否已开始事务的机制似乎没有任何错误,并且调用者不会在不抛出异常并记录它的情况下回滚。我没有找到任何回滚的交易痕迹。

  1. &#34; cascade&#34;是否存在问题父映射中的选项?
  2. 是因为事务提交发生在父项集合中添加子项之前吗?
  3. 在任何一种情况下,为什么孩子只在少数情况下失踪。这很难处理,并且可能会在生产中无声地造成很多问题。造成这种情况的原因是什么?

1 个答案:

答案 0 :(得分:1)

  1. 没有
  2. 没有
  3. 我敢打赌你的交易处理机制有一个缺陷,而且交易有时根本没有提交。它最终收集垃圾,导致它被静默处理和滚动。如果在事务提交之前发生会话conf/log4j.properties,则会发生这种情况。

    您可以通过记录事务启动/提交/回滚以及相关的上下文信息来跟踪它,以便与提交和回滚进行匹配。

    这可能非常棘手。什么是相关的背景信息?它在很大程度上取决于应用类型在IIS下的Web应用程序中,线程上下文不好,调用上下文不好。在asp.net线程敏捷切换的情况下,它们都会丢失,这会在负载下发生。在大多数情况下,仅保留HTTP上下文。 (并注意Close配置“回调”配置为在没有任何上下文的情况下运行...)