首页 新闻 搜索 专区 学院

NHibernate 一对一关系出错: attempted to assign id from null one-to-one property???

0
悬赏园豆:50 [已解决问题] 解决于 2012-05-22 13:06

情况如下:

public abstract class Entity

{

   public virture int Id{get;set;}

   protected virture int Version{get;set;}

}

public class Product:Entity

{

   public virture string Name{get;set;}

   public virture string Price{get;set;}

   ///产品的公共属性类

   public virture ProductAttr pa{get;set;}

}

//产品属性类,与上面的产品类[Product] 一对一关系

public class ProductAttr

{

   public virture int ProductId{get;set;}

   public virture int Height{get;set;}

   public virture int Width{ get;set;}

   public virture int Weight{get;set;}

   public virture Product Product{get;set;}

}

然后

我的Product.hbm.xml

....

<one-to-one name="pa" class="ProductAttr"  cascade="all"/>

 

我的ProductAttr.hbm.xml

....

<id name="ProductId"  column="ProductId"   type="Int32" unsaved-value="0">               

 <generator>     

      <paramname="property">Product</param>    

  </generator>

</id>

<one-to-one name="Product" class="Product" constrained="true"/>

 

在数据保存的时候,

var newproduct=new Peoduct{

 Name="111",

 Price = 20,

 pa=new ProductAttr{

   height=20,

   width=12,

   weight=33

}

};

 结果保存到数据库的时候,出现错误。

attempted to assign id from null one-to-one property: pa

但是如果把cascade="all" 去掉。就只保存Product数据,ProductAttr不保存了。

请问这是怎么回事啊????????

吼吼吼的主页 吼吼吼 | 初学一级 | 园豆:73
提问于:2012-04-26 20:07
< >
分享
最佳答案
0
       /// <summary>
        /// 使用User与Post的单向一对多关系
        /// </summary>
        [Test]
        public void OneToManySetUnidirectional()
        {
            using (var session = SessionFactory.OpenSession())
            using (var tx = session.BeginTransaction())
            {
                var user = new User();
                var post1 = new Post();
                var post2 = new Post();
                var post3 = new Post();
                user.Posts.Add(post1);
                user.Posts.Add(post2);
                user.Posts.Add(post3);

                session.Save(user);
                //Save操作时,如果不设置级联效应(Cascade),需要手动为其多端集合分别调用Save操作,如果设置级联效应,则不需要了。
                //session.Save(post1);
                //session.Save(post2);
                //session.Save(post3);
                tx.Commit();
                //这时出现插入1条User和3条Post的SQL和3条更新Post的SQL
            }
        }
        /// <summary>
        /// 使用Post与User的单向多对一关系
        /// </summary>
        [Test]
        public void ManyToOneSetUnidirectional()
        {
            using (var session = SessionFactory.OpenSession())
            using (var tx = session.BeginTransaction())
            {
                var user = new User();
                var post1 = new Post { User = user };
                var post2 = new Post { User = user };
                var post3 = new Post { User = user };
                session.Save(user);
                session.Save(post1);
                session.Save(post2);
                session.Save(post3);
                tx.Commit();
                //这时出现插入1条User和3条Post的SQL
            }
        }
        /// <summary>
        /// 使用User与Post的双向一对多关系
        /// </summary>
        [Test]
        public void OneToManySetBidirectional()
        {
            using (var session = SessionFactory.OpenSession())
            using (var tx = session.BeginTransaction())
            {
                var user = new User();
                var post1 = new Post { User = user };
                var post2 = new Post { User = user };
                var post3 = new Post { User = user };
                //建立从Post到User的关系,即可以从Post取出User
                //主控权在Post这一方,NHibernate在将Post写到数据库时,就一起连同外键写入Post类所对应的Table中
                user.Posts.Add(post1);
                user.Posts.Add(post2);
                user.Posts.Add(post3);
                //建立从User到Post的关系,即可以从User取出Post
                //主控权在User这一方,然而外键并不在User类所对应的表中,因此NH必须生成3个Update语句
                session.Save(user);
                tx.Commit();
                //配置inverse="true",即User放弃控制权:插入1条User和3条Post的SQL

                //当NH在存储面向对象的双向引用关系时,会分别为双边的引用关系去维护数据库的外键,但是在数据库的世界里,只要写一次外键即可。
                //我们可以通过inverse="true"的设置,让NH放弃维护一边的引用关系以减少不必要的Update语句。
                //对于Set、Bag集合,inverse都在“一对多”的“一”方(即主控权在“多”的一方)
            }
        }
收获园豆:30
李永京 | 老鸟四级 |园豆:3114 | 2012-04-26 23:16

我的问题是双向一对一关系。还是用NHibernate中自带的工具生成的数据表。

对了,还有为什么生成的数据表之间没有设置级联呢???

吼吼吼 | 园豆:73 (初学一级) | 2012-05-03 12:27

原来是大神啊~!!  我就是看你的教程接触的NHibernate!!谢谢啦~!

吼吼吼 | 园豆:73 (初学一级) | 2012-05-03 12:35

@吼吼吼: 不要用生成器

李永京 | 园豆:3114 (老鸟四级) | 2012-05-03 20:24
其他回答(1)
0

这里跟你的原因一样:http://stackoverflow.com/questions/882239/nhibernate-saving-new-parent-object-while-creating-a-child-object

http://topic.csdn.net/u/20090506/17/1d19acf4-e569-43df-9c53-5421dcce8dc2.html

http://www.coderanch.com/t/216725/ORM/java/help-one-one-child-data

I guess your project must be run on Sql Server. you could try this:
----------------------------
<generator /> 

and

<one-to-one name="address" />
----------------------------


then before the object of address setter for person , you must be persistent
the person object .

https://forum.hibernate.org/viewtopic.php?f=25&t=974225&view=previous

收获园豆:20
悟行 | 园豆:12422 (专家六级) | 2012-04-26 22:26
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册