国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Hibernate 中的 unsaved-value 的重要性

Hibernate 中的 unsaved-value 的重要性


由有本人剛學習 Hibernate 不就,不是很明白這里面的道理,故先記錄下:
先將這個示例說說:
create table category (
  catid char(10) not null,
  name varchar(80) null,
  descn varchar(255) null,
  constraint pk_category primary key (catid)
) type=InnoDB;

create table product (
  productid char(10) not null,
  category char(10) not null,
  name varchar(80) null,
  descn varchar(255) null,
  constraint pk_product primary key (productid),
  constraint fk_product_1 foreign key (category) references category (catid)
) type=InnoDB;

Category 和 Product 的關(guān)系是一對多的關(guān)系。
Category.java 和 Product.java 就是 POJO。

Category.hbm.xml:
    <class name="Category" table="category">
        <id name="catid" column="catid" type="java.lang.String" >
            <generator class="assigned"/>
        </id>
 
        <property name="name" column="name" type="java.lang.String" />
        <property name="descn" column="descn" type="java.lang.String" />
       
        <set name="products" table="product" inverse="true" cascade="all">
            <key column="category"/>
            <one-to-many class="Product"/>
        </set>
    </class>

Product.hbm.xml:
    <class name="Product" table="product">
        <id name="productid" column="productid" type="java.lang.String" >
            <generator class="assigned"/>
        </id>
 
        <property name="name" column="name" type="java.lang.String" />
        <property name="descn" column="descn" type="java.lang.String" />
       
        <many-to-one name="category"
                     column="category"
                     class="Category"/>
        
    </class>

測試的類:
protected void setUp() throws Exception {
  sessionFactory = new Configuration().configure().buildSessionFactory();
  session = sessionFactory.openSession();
 }

 protected void tearDown() throws Exception {
  session.close();
  sessionFactory.close();
 }
 
 public void testSave() throws Exception {
  Category cat = new Category();
  cat.setCatid("FISH");
  cat.setName("Fish");
  cat.setDescn("<image src=\"../images/fish_icon.gif\"><font size=\"5\" color=\"blue\"> Fish</font>");
  
  Product pro = new Product();
  pro.setProductid("K9-BD-01");  
  pro.setName("Bulldog");
  pro.setDescn("<image src=\"../images/dog2.gif\">Friendly dog from England");
  pro.setCategory(cat);
  cat.getProducts().add(pro);
 
  
  Transaction tx= session.beginTransaction();  
  session.save(cat);
  tx.commit();
 }
結(jié)果就出現(xiàn)摘要中所說的錯誤:
Hibernate: insert into category (name, descn, catid) values (?, ?, ?)
Hibernate: update product set name=?, descn=?, category=? where productid=?
10:07:08,062 ERROR SessionImpl:2399 - Could not synchronize database state with session

但將兩個 *.hbm.xml 文件中的
<id name="catid" column="catid" type="java.lang.String"> 改為
<id name="catid" column="catid" type="java.lang.String" unsaved-value="any">
<id name="productid" column="productid" type="java.lang.String">  改為
<id name="productid" column="productid" type="java.lang.String" unsaved-value="any">
測試正常。

從夏昕的 Hibernate 開發(fā)指南中可以看到他介紹的 “關(guān)于unsaved-value”:

在非顯示數(shù)據(jù)保存時,Hibernate將根據(jù)這個值來判斷對象是否需要保存。
所謂顯式保存,是指代碼中明確調(diào)用session 的save、update、saveOrupdate 方法對對象進行持久化。如:session.save(user);
而在某些情況下,如映射關(guān)系中,Hibernate 根據(jù)級聯(lián)(Cascade)關(guān)系對聯(lián)接類進行保存。此時代碼中沒有針對級聯(lián)對象的顯示保存語句,需要Hibernate 根據(jù)對象當前狀態(tài)判斷是否需要保存到數(shù)據(jù)庫。此時,Hibernate即將根據(jù)unsaved-value進行判定。
首先Hibernate會取出目標對象的id。
之后,將此值與unsaved-value進行比對,如果相等,則認為目標對象尚未保存,否則,認為對象已經(jīng)保存,無需再進行保存操作。如:user對象是之前由hibernate從數(shù)據(jù)庫中獲取,同時,此user對象的若干個關(guān)聯(lián)對象address 也被加載,此時我們向user 對象新增一個address 對象,此時調(diào)用 session.save(user),hibernate會根據(jù)unsaved-value判斷user對象的數(shù)個address 關(guān)聯(lián)對象中,哪些需要執(zhí)行save操作,而哪些不需要。
對于我們新加入的address 對象而言,由于其id(Integer 型)尚未賦值,因此為null,與我們設(shè)定的unsaved-value(null)相同,因此hibernate將其視為一個未保存對象,將為其生成insert語句并執(zhí)行。這里可能會產(chǎn)生一個疑問,如果“原有”關(guān)聯(lián)對象發(fā)生變動(如user的某個“原有”的address對象的屬性發(fā)生了變化,所謂“原有”即此address對象已經(jīng)與user相關(guān)聯(lián),而不是我們在此過程中為之新增的),此時id值是從數(shù)據(jù)庫中讀出,并沒有發(fā)生改變,自然與unsaved-value(null)也不一樣,那么Hibernate是不是就不保存了?
上面關(guān)于PO、VO 的討論中曾經(jīng)涉及到數(shù)據(jù)保存的問題,實際上,這里的“保存”,實際上是“insert”的概念,只是針對新關(guān)聯(lián)對象的加入,而非數(shù)據(jù)庫中原有關(guān)聯(lián)對象的“update”。所謂新關(guān)聯(lián)對象,一般情況下可以理解為未與Session 發(fā)生關(guān)聯(lián)的VO。而“原有”關(guān)聯(lián)對象,則是PO。如上面關(guān)于PO、VO的討論中所述:對于save操作而言,如果對象已經(jīng)與Session相關(guān)聯(lián)(即已經(jīng)被加入Session的實體容器中),則無需進行具體的操作。因為之后的Session.flush過程中,Hibernate 會對此實體容器中的對象進行遍歷,查找出發(fā)生變化的實體,生成并執(zhí)行相應(yīng)的 update 語句。

針對上面的例子,當沒有設(shè)定 unsaved-value="any" 時,也就相當于 unsaved-value="none",不論主鍵屬性為任何值,都不可能為 none,因此 Hibernate 總是對 product 對象發(fā)送update(product);unsaved-value="any" 的時候,由于不論主鍵屬性為任何值,都肯定為 any,因此 Hibernate 總是對 product 對象發(fā)送 save(product)。

所以 Hibernate.org.cn 論壇中的 Robbin 建議在系統(tǒng)設(shè)計的時候,遵循如下原則:

1、使用Hibernate的id generator來生成無業(yè)務(wù)意義的主鍵,不使用有業(yè)務(wù)含義的字段做主鍵,不使用assigned。

2、使用對象類型(String/Integer/Long/...)來做主鍵,而不使用基礎(chǔ)類型(int/long/...)做主鍵

3、不使用composite-id來處理復合主鍵的情況,而使用UserType來處理該種情況。


那么你永遠用的是unsaved-value="null" ,不可能用到any/none/..了。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
在Hibernate應(yīng)用中Java對象的狀態(tài)
收藏:關(guān)于unsaved-value 的再問 qingzhuang
Hibernate 臟數(shù)據(jù)檢查
一個用myeclipse開發(fā)hibernate的入門例子 - 我愛JAVA - BlogJ...
關(guān)于Hibernate中l(wèi)oad與get的討論
Hibernate緩存機制
更多類似文章 >>
生活服務(wù)
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服