hibernate merge attempted to assign id from null one-to-one property<亲测>

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的不全也会报错

 

 

posted @ 2013-02-18 17:01  小哥哥啊  阅读(569)  评论(0编辑  收藏  举报