情况如下:
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不保存了。
请问这是怎么回事啊????????
/// <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都在“一对多”的“一”方(即主控权在“多”的一方) } }
我的问题是双向一对一关系。还是用NHibernate中自带的工具生成的数据表。
对了,还有为什么生成的数据表之间没有设置级联呢???
原来是大神啊~!! 我就是看你的教程接触的NHibernate!!谢谢啦~!
@吼吼吼: 不要用生成器
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