2011-09-20 86 views
5

我有一個UserProfile實體,需要保存。拯救實體數據庫後,我得到以下異常:使用Spring Hibernate獲取事務未成功啓動異常

Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started 

而且當我看到桌上的實體持久的而不是做一回退!

@Transactional(isolation=Isolation.REPEATABLE_READ) 
public class HibernateUserProfileDAO implements UserProfileDAO { 
    private org.hibernate.SessionFactory sessionFactory; 
    public UserProfile getUserProfile(int userId) { 
     org.hibernate.classic.Session session = sessionFactory.getCurrentSession(); 
     session.beginTransaction(); 
     UserProfile userProfile = new UserProfile(); 
     userProfile.setUserName("sury1"); 
     session.save(userProfile); 
     session.getTransaction().commit(); 
     session.close(); 
     return userProfile; 
    } 
} 

我使用Hibernate事務經理

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory"/> 
</bean> 

和我的休眠配置爲:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="packagesToScan" value="com.springheatmvn.domain"/> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.connection.pool_size">10</prop> 
      <prop key="hibernate.connection.show_sql">true</prop> 
      <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
      <prop key="hibernate.hbm2ddl.auto">update</prop> 
     </props> 
    </property>  
</bean> 

任何人都可以PL。告訴我這裏發生了什麼事?

+0

'@ user354161'請參閱'Bozho'編輯答案和評論 – Bitmap

回答

10

我認爲你已經成爲雙重交易管理的受害者。如果您在同一個項目中同時使用Spring Transaction ManagementHibernate Transaction Management,則更可能出現此問題。

你的代碼,那麼要麼是:

選項1.Hibernate事務管理

public class HibernateUserProfileDAO implements UserProfileDAO { 
    private org.hibernate.SessionFactory sessionFactory; 
    public UserProfile getUserProfile(int userId) { 
     org.hibernate.classic.Session session = sessionFactory.getCurrentSession(); 
     session.beginTransaction(); 
     UserProfile userProfile = new UserProfile(); 
     userProfile.setUserName("sury1"); 
     session.save(userProfile); 
     session.getTransaction().commit(); 
     session.close(); 
     return userProfile; 
    } 
} 

選項2Spring事務管理

@Transactional 
public class HibernateUserProfileDAO implements UserProfileDAO { 
    private org.hibernate.SessionFactory sessionFactory; 
    public UserProfile getUserProfile(int userId) { 
     org.hibernate.classic.Session session = sessionFactory.getCurrentSession(); 
     UserProfile userProfile = new UserProfile(); 
     userProfile.setUserName("sury1"); 
     session.save(userProfile); 
     session.close(); 
     return userProfile; 
    } 
} 
+1

yup,使用@Transactional或.beginTransactional()。此外 - 彈簧事務不支持更改隔離級別 – Bozho

+0

Spring事務確實支持隔離級別更改,但僅限於'DataSourceTransactionManager'。 還有一個包裝類,可以在Hibernate tx管理器中使用'org.springframework.jdbc.datasource.IsolationLevelDataSourceAdapter'。但是,如果你在不同的地方需要不同的隔離級別,你必須管理單獨的Hibernate TX管理器,這可以用AOP完成,但不能用'@ Transactional'註釋。 – AngerClown

+0

謝謝你們!現在它爲我工作了!我使用@Bitmap建議的選項2。 只需在選項2中進行一次更正,我們還需要刪除session.close()語句,因爲sessionFactory.getCurrentSession()會自動關閉會話。當我有了session.close()語句時,我得到了org.hibernate.SessionException:Session被關閉了!例外。 再次感謝! – tintin

0

也可能是org.springframework.orm.hibernate3.HibernateTemplateorg.hibernate.Session之間的衝突。

如果您正在處理一箇舊項目,您可以找到HibernateTemplate正在使用。

如果您使用更新的方式創建新的DAO,如hibernate的Session,並且在同一個函數上使用這兩個DAO,則會發現此錯誤。

解決方案:使用其中一個或另一個。在我的情況下,我不得不使用HibernateTemplate爲了不改變一箇舊程序的其餘部分。

相關問題