2015-07-19 105 views
0

我在Hibernate的自我訓練。 我剛剛發現奇怪的行爲,我不解釋了。休眠不要保存我的對象

我使用Hibernate的4.3.10與Java 8

我希望你能幫助我明白髮生了什麼。 更明確的看到下面的代碼示例:

public static long createBlindStructure(BlindStructure pBlindStructure){ 
    Transaction tcx = null; 
    SessionFactory factory = HibernateUtil.getSessionFactory(); 
    Session session = factory.openSession(); 
    int id = -1; 
    try{ 
     tcx = session.beginTransaction(); 
     id = session.save(pBlindStructure); 
     tcx.commit(); 
    } 
    catch(Throwable e){ 
     tcx.rollback(); 
    } 
    finally{ 
     session.close(); 
    } 
    return id; 
} 

在我看來這種方法保存打開的會話和交易,拯救我的對象,然後關閉會話和交易。從保存我試圖找回javadoc中描述的標識符。但它不起作用,我看到請求在我的日誌中執行(感謝休眠調試模式)。

Hibernate: insert into PokerLeagueManager.blindStructure (structureJson) values (?) 

但當我嘗試這個辦法:

public static long createBlindStructure(BlindStructure pBlindStructure){ 
    Transaction tcx = null; 
    SessionFactory factory = HibernateUtil.getSessionFactory(); 
    Session session = factory.openSession(); 
    try{ 
     tcx = session.beginTransaction(); 
     session.save(pBlindStructure); 
     tcx.commit(); 
    } 
    catch(Throwable e){ 
     tcx.rollback(); 
    } 
    finally{ 
     session.close(); 
    } 
    return pBlindStructure.getIdBlindStructure(); 
} 

它正確保存我的對象。

我測試更多的情況: 就返回一個常量,不要把標識的變量像第一個例子和它的工作。看來這個對象不會保存,以防直接用「session.save」方法獲得ID。

此外,我注意到一些有趣的事情。我做第一個試驗與工作解決方案之一,它產生的ID爲117數據庫中的數據然後我改變我的代碼不Tomcat中工作,並重新加載它的解決方案,我做2嘗試沒有成功。我再次改變我對所產生的其中一個成功的ID碼120.錯過2 ID號(2試試我做?)

爲了幫助你看到我的hibernate.cfg.xml文件

<?xml version='1.0' encoding='UTF-8'?> 
<!DOCTYPE hibernate-configuration PUBLIC 
      '-//Hibernate/Hibernate Configuration DTD 3.0//EN' 
      'http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd'> 

<hibernate-configuration> 
<session-factory> 
    <!-- Database connection settings --> 
    <property  name='connection.driver_class'>com.mysql.jdbc.Driver</property> 
    <property name='connection.url'>jdbc:mysql://XXXXXX:XXXX/PokerLeagueManager</property> 
    <property name='connection.username'>XXXXX</property> 
    <property name='connection.password'>XXXXXX</property> 
    <property name="show_sql">true</property> 

    <!-- JDBC connection pool (use the built-in) --> 
    <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> 
    <property name="hibernate.c3p0.acquire_increment">1</property> 
    <property name="hibernate.c3p0.idle_test_period">120</property> 
    <property name="hibernate.c3p0.min_size">1</property> 
    <property name="hibernate.c3p0.max_size">10</property> 
    <property name="hibernate.c3p0.max_statements">50</property> 
    <property name="hibernate.c3p0.timeout">120</property> 
    <property name="hibernate.c3p0.acquireRetryAttempts">1</property> 
    <property name="hibernate.c3p0.acquireRetryDelay">250</property> 
    <!-- Dev --> 
    <property name="hibernate.c3p0.validate">true</property> 

    <!-- SQL dialect --> 
    <property name='dialect'>org.hibernate.dialect.MySQL5InnoDBDialect</property> 

    <!-- Enable Hibernate's automatic session context management --> 
    <property name="current_session_context_class">thread</property> 
    <!-- Disable the second-level cache --> 
    <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property> 


    <!-- Echo all executed SQL to stdout --> 
    <property name='show_sql'>true</property> 

    <mapping resource="mappings/BlindStructure.hbm.xml"/> 
    <mapping resource="mappings/Tournament.hbm.xml"/> 
    <mapping resource="mappings/LegalFee.hbm.xml"/> 
</session-factory> 

編輯:用戶3813463回答問題的一部分。它解釋說,會議是在自動刷新模式在默認情況下它在像一些情況下衝洗會議:

沖洗默認情況下在以下幾點情況:

  • 在某些查詢執行

  • 來自org.hibernate.Transaction.commit()

  • from Session.flush()

但我以我的觀點(我可能想念某事),我的第一個案例應該工作,因爲我犯了我的交易。其次,我需要建議選擇一種沖洗模式。在我看來,對於僅在數據庫中插入或僅讀取數據的方法,「提交」模式是一種很好的方法。

你是否同意我的觀點,你有一些資料來源,這是辯論嗎?

+0

如果你不介意第一次你能回答我的問題,你看到在控制檯/日誌當行'返回pBlindStructure.getIdBlindStructure();'得到執行? :) – Amogh

+0

...併發布您的休眠配置... – Amogh

+0

pBlindStructure.getIdBlindStructure()=>它返回我的第二種情況下生成的Id的值。我在主消息 – Wodric

回答

1

這一切的FlushMode讀取文檔here

根據文檔默認FlushModeAUTO這意味着

會話,以便查詢執行之前有時刷新到 確保魔術查詢永遠不會返回陳舊狀態。

根據另一個文件(Here):

flush在以下點發生默認:

之前某些查詢執行

從org.hibernate.Transaction.commit( )

from Session.flush()

所以,當你說pBlindStructure.getIdBlindStructure(); hibernate實際上在當前會話上執行刷新,結果數據被保存在數據庫中。

+0

對不起,如果不回答,我會在今天晚些時候研究你的答案,我最後一天沒有時間。 – Wodric

+0

對不起,延遲的答案,我有很多想做IRL;)。這解釋了爲什麼在我的第二種情況下,我一定會有結果。但我第一個案例是應該刷新當前會話的事務提交?在那種情況下,爲什麼它不是沖水呢?哪種刷新模式更適合在低併發應用程序中使用? – Wodric

0

會話保存方法爲生成器生成的ID返回一個對象。這個值應該投射到Long

long id = -1; 
try{ 
    tcx = session.beginTransaction(); 
    id = (Long) session.save(pBlindStructure); 
    tcx.commit(); 
} 
catch(Throwable e){ 
    tcx.rollback(); 
} 
finally{ 
    session.close(); 
} 
return id; 
+0

先生,但是爲什麼記錄沒有在方法1中保存呢?我認爲這是因爲'flushmode'。我認爲在第二種方法中,當'pBlindStructure.getIdBlindStructure();'得到執行會話刷新寫入(插入)記錄到DB。 – Amogh

+0

對不起,我忘了我的演員,但我在我的測試中完全像你(日食不要讓我選擇) – Wodric

+0

我沒有聽到你說的話。 –