一、外键字段必须是外键表的主键
描述:一张订单表:RechargeOrder,一张流水表记录:CardRechargeRecord。RechargeOrder是主表,CardRechargeRecord是子表,RechargeOrder的OrderSeq(订单号)是CardRechargeRecord的外键,但OrderSeq并不是RechargeOrder的主键(另外有一个自动增长的id是作为主键,当然,不是主键的键是可以作为外键使用的,只要它是唯一的),在做nhibernate 的实体文件配置文件中,做RechargeOrder和CardRechargeRecord的一对多配置。
问题一:那么通过RechargeOrder的外键关系获取CardRechargeRecord信息或者通过CardRechargeRecord获取RechargeOrder信息是获取不到的,均会报“illegal access to loading collection”错误。
原因:如果要在nhibernate中做一对多配置,那么主表的那个外键列必须作为主键,否则不行。
解决方法:将OrderSeq列改为RechargeOrder的主键列就ok了。
二、如何设置非主键的自动增长id
如上,刚把RechargeOrder表的OrderSeq列重新修改为了主键,按道理说,以前设置的自动增长的主键id是可以不需要的,但是现在不想删除该id字段,保留着以后有用,而且id仍旧是自动增长的,我们知道,在nhibernate中的主键自动增长可以做如下设置:
<id name="ID" column="ID" type="long">
<generator class="native" />
</id>
但是,对于非主键的字段是不能这样设置,现在又有一个新问题:在进行实体插入的时候会报类似“当 IDENTITY_INSERT 设置为 OFF 时,不能为表 'RechargeOrder' 中的标识列插入显式值”这样的错误。
原因:因为id字段是自动增长的,但是因为在配置文件中没有配置,所以程序又是不知道的,在插入时又进行插入,这样就会报这样的错误。
解决方法:修改id属性的配置增加“insert="false"”,如下:<property name="ID" column="ID" type="long" insert="false"/>,这样就可以进行插入操作了。同样,还要加上“update="false"”配置,如果不加的话,那么在修改更新信息的时候也会报同样的错误,加上这两个配置,其实就是不让程序去更新和修改id这个字段的信息,因为这个id的值有数据库去控制,这样就可以达到想要的目的了。