這是我在學習使用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了。