2016-06-08 48 views
0

我有以下实体:NHibernate的通过码 - 保存未保存(瞬态)的子实体实体

public class Item 
{ 
public virtual long ID { get; set; } 
public virtual Version Version { get; set;} 
More properties... 
} 

在实体映射我有:

ManyToOne(p => p.Version, m => 
{ 
m.Column("VERSION_ID"); 
} 

实体Version也被映射代码,它的ID是一个自动生成的序列。 当我保存Item时,我创建了一个新的Version,将其分配给Version属性并保存。我只想在Item成功保存后才保存Version实体。现在,当我这样做时,它会抛出一个TransientObjectException。有没有可能解决这个问题?

回答

1

除非映射指定Cascade.Persist或Cascade.All的属性,否则不能通过映射属性(Item-> Version)保存引用瞬态对象的实体。

另一件事是,因为你应该在一个事务中运行该代码,插入顺序应该没有关系。如果在保存版本后但在保存项目之前引发异常(或发生其他情况),则应回退事务,并且没有人会看到新版本。

下面的代码片段展示了如何使用nHibernate开始/提交事务。注意,如果事务在处理之前没有被提交,事务将被回滚。

using(var session = sessionFactory.OpenSession()) 
using(var transaction = session.BeginTransaction()) 
{ 
    // Do your thing here... 

    transaction.Commit(); 
} 
+0

所以级联意味着子实体会与父级一起保存,并且会在出现错误时回滚? – user6251216

+1

Cascade.Persit将在保存父项时(明确地或当会话刷新时)保存所引用的实体。您有责任在交易中执行此操作,以便在发生问题时可以回滚。我已经用一个片段更新了答案,显示了如何完成。 –

+0

该实体与运行代码分开保存,因此难以访问该事务。我想我必须处理Cascade.All这个工作。 – user6251216

相关问题