hibernate merge attempted to assign id from null one-to-one property
首先有两个数据表Topic和TopicInfo。Topic为主表,TopicInfo为从表,建表语句如下:
Topic:
CEATE TABLE `topic` ( `topic_name` varchar(100) COLLATE utf8_bin NOT NULL, `topic_id` varchar(100) COLLATE utf8_bin NOT NULL, `uid` varchar(100) COLLATE utf8_bin NOT NULL, PRIMARY KEY (`topic_id`), KEY `topic_uid` (`uid`), CONSTRAINT `topic_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
------------------------------------------------------------------
TopicInfo:
CREATE TABLE `topic_info` ( `topic_info_id` varchar(100) COLLATE utf8_bin NOT NULL, `topic_type` varchar(100) COLLATE utf8_bin NOT NULL, `topic_num` varchar(100) COLLATE utf8_bin NOT NULL, `topic_approve_num` varchar(100) COLLATE utf8_bin NOT NULL, `topic_entrustUnit` varchar(100) COLLATE utf8_bin NOT NULL, `topic_approveDate` date NOT NULL, `topic_avildTime` date NOT NULL, `topic_director` varchar(100) COLLATE utf8_bin NOT NULL, `topic_funds` int(10) NOT NULL, `topic_director_depart` varchar(100) COLLATE utf8_bin NOT NULL, `topic_summary` varchar(1000) COLLATE utf8_bin DEFAULT NULL, PRIMARY KEY (`topic_info_id`), UNIQUE KEY `topic_info_id` (`topic_info_id`), CONSTRAINT `topic_info_ibfk_1` FOREIGN KEY (`topic_info_id`) REFERENCES `topic` (`topic_id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
Topic.hbm.xml配置文件:
<hibernate-mapping package="com.du.domain"> <class name="Topic" table="topic" lazy="false"> <id name="topicId" column="topic_id"> <generator class="assigned"/> </id> <property name="topicName" column="topic_name" unique="true" type="java.lang.String"/> <many-to-one name="user" column="uid" class="User" cascade="all" lazy="false"/> <one-to-one name="topicInfo" class="com.du.domain.TopicInfo" cascade="all" lazy="false"/> </class> </hibernate-mapping>
TopicInfo.hbm.xml 配置文件
<hibernate-mapping package="com.du.domain"> <class name="TopicInfo" table="topic_info" lazy="false"> <id name="topicInfoId" column="topic_info_id"> <generator class="foreign"> <param name="property">topic</param> </generator> </id> <!-- 和topic的一对一外键关系 --> <one-to-one name="topic" class="com.du.domain.Topic" cascade="all" constrained="true"/> <property name="topicApproveDate" column="topic_approveDate" type="java.util.Date"/> <property name="topicApproveNum" column="topic_approve_num"/> <property name="topicAvildTime" column="topic_avildTime" type="java.util.Date"/> <property name="topicEntrustUnit" column="topic_entrustUnit"/> <property name="topicType" column="topic_type"/> <property name="topicNum" column="topic_num"/> <property name="topicDirector" column="topic_director"/> <property name="topicFunds" column="topic_funds"/> <property name="topicSummary" column="topic_summary"/> <property name="topicDirectorDepart" column="topic_director_depart"></property> </class> </hibernate-mapping>
要注意的是:因为Topic表为主表,所以在配置<one-to-one>属性的时候要加上 cascade="all" ,不能换成none否则会出错。同时在TopicInfo <one-to-one> 配置端
cascade="all" constrained="true" 特别注意constrained="true"---可以参考下面一段话
---------------------------------------------
constrained默认值为false
constrained只能在one-to-one的映射中使用,(一般在主表的映射中,有外键的那个表)。如果
constrained=true, 则表明存在外键与关联表对应,并且关联表中肯定存在对应的键与其对应, 另外该选项最关键的是影响save和delete的先后顺序。例如增加的时候,如果constainted=true,则会先增加关联表,然后增加本表。 删除的时候反之。
one-to-one的单向关联中,如果constrained=false,则会在查询时就全部取出来,用left outer join的方式。如果constrained=true,hibernate即会延迟加载sql,只把主表的查出来,等有用到关联表的再发sql取。
one-to- one的双向关联中,必须设置constrained=true,要不然会有重复数据读,如2个表user,car;在位false时sql如 下:select * from user a left outer join car b on a.id=b.id left outer join on user c on a.id=c.id where a.id=? 删除的时候最好删除从表,删除主表会先查询下主表,在联合查询下。
此处摘自---http://blog.csdn.net/linminqin/article/details/6324567
--------------------------------------
而且要注意的是在保存持久化对象之前:主表.setXXX(从表);然后是:从表.setXXX(主表);若不set或者set的不全也会报错