簡體   English   中英

休眠不保存我的對象

[英]Hibernate don't save my object

我在Hibernate進行自我訓練。 我只是發現了我不解釋的奇怪行為。

我在Java 8中使用Hibernate 4.3.10

希望您能幫助我了解發生了什么。 更明確地說,請參見以下代碼示例:

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();
}

它正確保存了我的對象。

我再測試一種情況:僅返回一個常量,而不像第一個示例那樣將Id放入變量中,並且它起作用。 如果我直接通過“ session.save”方法獲取ID,似乎該對象未保存。

此外,我觀察到一些有趣的事情。 我使用其中一個有效的解決方案進行了第一個測試,它使用ID 117生成了數據庫數據。然后,我更改了無效的解決方案的代碼,並將其重新加載到tomcat中,我進行了兩次嘗試,但均未成功。 我再次更改代碼,成功的代碼生成的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>

編輯:User3813463答案的一部分問題。 它說明了會話默認情況下處於自動刷新模式,在某些情況下該會話刷新為:

默認情況下,刷新發生在以下幾點:

  • 在執行某些查詢之前

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

  • 來自Session.flush()

但是我的觀點是(我可能會想念一些東西),我的第一種情況應該奏效,因為我提交了交易。 其次,我需要建議選擇沖洗模式。 在我看來,提交模式是僅對數據庫進行插入或讀取的方法的好方法。

您是否同意我的看法?

這就是FlushMode的魔力,請在此處閱讀文檔

根據文檔,默認FlushModeAUTO ,這意味着

有時在執行查詢之前會刷新會話,以確保查詢從不返回過時狀態。

根據另一個文件( here ):

默認情況下, flush發生在以下幾點:

在執行某些查詢之前

來自org.hibernate.Transaction.commit()

來自Session.flush()

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

會話保存方法返回由生成器生成的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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM