hibernate 具有主外键关系的多表级联保存

来源:互联网 发布:淘宝卖家版下载官方 编辑:程序博客网 时间:2024/05/01 08:35

这是我在学习使用hibernate进行多表级联保存时,遇到的问题,记录下来以便日后查找。


微博图片表

SayFiles.hbm.xml

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!--     Mapping file autogenerated by MyEclipse Persistence Tools--><hibernate-mapping>    <class name="com.gifer.model.SayFiles" table="SAY_FILES" schema="GIFER">        <id name="fileId" type="java.lang.Long">            <column name="FILE_ID" precision="18" scale="0" />            <generator class="sequence">            <param name="sequence">SEQ_SAY_FILES</param>            </generator>        </id>        <many-to-one name="sayMessage" class="com.gifer.model.SayMessage" fetch="select">            <column name="SAY_ID" precision="18" scale="0" />        </many-to-one>        <property name="fileName" type="java.lang.String">            <column name="FILE_NAME" length="200" />        </property>        <property name="fileUrl" type="java.lang.String">            <column name="FILE_URL" length="200" />        </property>        <property name="uploadTime" type="java.sql.Timestamp">            <column name="UPLOAD_TIME" length="7" />        </property>    </class></hibernate-mapping>


微博主表

SayMessage.hbm.xml

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!--     Mapping file autogenerated by MyEclipse Persistence Tools--><hibernate-mapping>    <class name="com.gifer.model.SayMessage" table="SAY_MESSAGE" schema="GIFER">        <id name="sayId" type="java.lang.Long">            <column name="SAY_ID" precision="18" scale="0" />            <generator class="sequence">            <param name="sequence">SEQ_SAY_MESSAGE</param>            </generator>        </id>        <property name="sayContent" type="java.lang.String">            <column name="SAY_CONTENT" length="280" not-null="true" />        </property>        <property name="sayTime" type="java.sql.Timestamp">            <column name="SAY_TIME" length="7" not-null="true" />        </property>        <property name="sayUser" type="java.lang.String">            <column name="SAY_USER" length="50" not-null="true" />        </property>        <set name="sayFileses" inverse="true"  cascade="save-update" >            <key>                <column name="SAY_ID" precision="18" scale="0" />            </key>            <one-to-many class="com.gifer.model.SayFiles" />        </set>        <set name="replyMessages" inverse="true">            <key>                <column name="SAY_ID" precision="18" scale="0" />            </key>            <one-to-many class="com.gifer.model.ReplyMessage" />        </set>    </class></hibernate-mapping>

微博图片表SayFiles的SAY_ID属性依赖于微博主表SayMessage的主键SAY_ID

action处理代码

// 组织成微博实体对象SayMessage sayMessage = new SayMessage();sayMessage.setSayContent(this.getSayMessage());Timestamp sayTime = new Timestamp(System.currentTimeMillis());sayMessage.setSayTime(sayTime);// 当前时间LoginUser sayUser = (LoginUser) ActionContext.getContext().getSession().get("user");// 从session中获取用户信息sayMessage.setSayUser(sayUser.getUserId());Set sayFiles = new HashSet();// 把得到的文件的集合通过循环的方式读取并放在指定的路径下for (int i = 0; i < upload.size(); i++) {try {SayFiles sayFile = new SayFiles();String oldFileName = uploadFileName.get(i);// 上传文件原名// 生成随机文件名:当前年月日时分秒+五位随机数(为了在实际项目中防止文件同名而进行的处理)Random r = new Random();int rannum = (int) (r.nextDouble() * (99999 - 10000 + 1)) + 10000; // 获取随机数SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); // 时间格式String nowTimeStr = sDateFormat.format(new Date()); // 当前时间字符串String extName = "";// 获取拓展名if (oldFileName.lastIndexOf(".") >= 0) {extName = oldFileName.substring(oldFileName.lastIndexOf("."));}// 新文件名String newFileName = nowTimeStr + rannum + extName;relativeUrl += newFileName;// 文件保存到数据库中的相对路径// list集合通过get(i)的方式来获取索引// 将文件逐一复制到指定目录FileUtils.copyFile(upload.get(i), new File(files,newFileName));sayFile.setFileName(oldFileName);sayFile.setFileUrl(relativeUrl);sayFile.setUploadTime(sayTime);sayFile.setSayMessage(sayMessage);sayFiles.add(sayFile);} catch (IOException e) {log.error(e.getMessage(), e);}}sayMessage.setSayFileses(sayFiles);this.sayMessageService.save(sayMessage);//调用主键的保存方法

利用主表来保存,刚开始没有加cascade="save-update",结果,微博主表记录插入成功,微博图片表记录没有插入。

<set name="sayFileses" inverse="true" >            <key>                <column name="SAY_ID" precision="18" scale="0" />            </key>            <one-to-many class="com.gifer.model.SayFiles" />        </set>
加上属性:cascade="save-update"后,结果,微博主表记录插入成功,微博图片表记录插入也成功了,但是外键SAY_ID是null。

<set name="sayFileses" inverse="true"  cascade="save-update" >            <key>                <column name="SAY_ID" precision="18" scale="0" />            </key>            <one-to-many class="com.gifer.model.SayFiles" /></set>

原因是在给微博图片表实体,设置属性时,漏掉了下面这句,没有给其设置外键值的引用对象

sayFile.setSayMessage(sayMessage);

加上后,两个表的插入操作都OK了。








原创粉丝点击