【问题标题】:Hibernate saving entity not working休眠保存实体不起作用
【发布时间】:2015-01-30 15:04:13
【问题描述】:

我在我的项目中使用Spring 3.2 mvcHibernate 4

hibernate.cfg.xml

<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.autocommit">true</property>
<property name="show_sql">true</property>
  <property name="hibernate.c3p0.min_size">5</property>
  <property name="hibernate.c3p0.max_size">20</property>
  <property name="hibernate.c3p0.timeout">300</property>
  <property name="hibernate.c3p0.max_statements">50</property>
  <property name="hibernate.c3p0.idle_test_period">3000</property>
  <property name="hibernate.validator.apply_to_ddl">false</property> 
  <property name="hibernate.validator.autoregister_listeners">false</property>

servlet-context.xml

<beans:beans xmlns="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:beans="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:security="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
              http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/security
              http://www.springframework.org/schema/security/spring-security-3.2.xsd
              http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
              http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">



       <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
       <security:global-method-security pre-post-annotations="enabled"/>
       <!-- Enables the Spring MVC @Controller programming model -->
       <annotation-driven />
       <context:annotation-config />
       <context:component-scan base-package="com.abc" />

       <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
              <beans:property name="prefix" value="/WEB-INF/views/" />
              <beans:property name="suffix" value=".jsp" />
       </beans:bean>

</beans:beans>

DaoImpl 类

public void add(Entity entity) {

   try {
          this.sessionFactory.getCurrentSession().save(entity);
          this.sessionFactory.getCurrentSession().flush();
       } catch (Exception e) {
             logger.error("Exception occured " + e);
       } 
   }

这是我的project configurationdao impl class 文件。

root-context.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"  
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd 
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">

     <!-- <tx:annotation-driven transaction-manager="transactionManager" /> -->
     <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
     </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>

    <context:component-scan base-package="com.abc" />

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
       <!--  <property name = "dataSource" ref = "dataSource"></property>  -->
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
        <property name="entityInterceptor" ref ="auditLogInterceptor"/>
    </bean> 

问题
截至目前,在 hibernate.cfg.xml 中,我已经提到了 hibernate.connection.autocommit = true 并且在 daoimpl 中保存实体时我需要在 .save 之后调用 flush

如果我从 daoimpl 类中删除 hibernate.connection.autocommit = true 和 .flush,我观察到 daoimpl 中的 .save 方法不起作用,这意味着我的数据没有插入,甚至我看不到 hibernate 在控制台上执行的插入查询.

hibernate.connection.autocommit = true 不应该出现在 hibernate cfg xml 中,就像我在同一个事务中对多个表进行操作一样,如果发生一些错误,则不会发生回滚。

我希望 daoimpl 中的 .save 应该可以工作,即使我没有在 hibernate cfg xml 和 .flush 中写 hibernate.connection.autocommit = true。

我正在使用@Transactional 注释进行事务。

【问题讨论】:

  • 它是否返回任何错误消息/异常。您在哪种模式下运行休眠,即创建或更新
  • 检查是否有活动事务以及是否正在生成任何 sql
  • @Madusudanan :控制台上也不例外。
  • @André : 显示 sql 为真,但在控制台中看不到插入查询。
  • @VJS 你最近切换到 Hibernate 4 了吗?您的实体配置是否正确?

标签: java spring hibernate spring-mvc transactions


【解决方案1】:

您尚未将任何 TransactionManager 添加到您的配置中:

  1. 删除以下属性:

    <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
    <property name="hibernate.connection.autocommit">true</property>
    <property name="hibernate.c3p0.min_size">5</property>
    <property name="hibernate.c3p0.max_size">20</property>
    <property name="hibernate.c3p0.timeout">300</property>
    <property name="hibernate.c3p0.max_statements">50</property>
    <property name="hibernate.c3p0.idle_test_period">3000</property>
    
  2. 添加一个连接池DataSource(DBCP2是比C3P0更好的替代方案)

    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="your-oracle-driver-url"/>
        <property name="username" value="your-username"/>
        <property name="password" value="your-password"/>
    </bean>
    
  3. 现在添加 Sessionfactory Spring 代理:

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
    </bean>
    
  4. 添加 TransactionManager bean

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

更新

如果您在单独的 Spring 应用程序上下文(例如 root-context.xml)中设置了事务管理器,则将这些行从您的 Web 上下文移动到后端上下文:

<tx:annotation-driven transaction-manager="transactionManager"/>
<context:component-scan base-package="com.abc.service" />
<context:component-scan base-package="com.abc.dao" />

并且只允许 web 上下文扫描它自己的 bean:

<context:component-scan base-package="com.abc.web" />

It's not good to mix the web and the back-end contexts responsibilities.

【讨论】:

  • 我没有提到 root-context.xml,在这个 3 和 4 点配置中存在。即使这样,休眠也没有执行插入查询。我也没有任何例外。它似乎只是忽略了保存。
  • @Vlad Mihalcea:谢谢。我的问题的某个解决方案与组件扫描有关。从您的回答来看,似乎服务和 dao 包需要在 root-context.xml 中提及,而控制器包需要在 servlet-context.xml 中提及。我的困惑是:1)实体包也存在2)在服务层,我们正在为dao类进行spring自动装配。如果我在root-context.xml中提到服务包,那么spring自动装配注释将如何扫描。
  • 实体不应该被扫描并且应该对核心和网络都可用。一个上下文中的服务 bean 仍然可以在 Web 上下文中使用。
  • @Vlad Mihalcea:谢谢。
【解决方案2】:

我的问题解决了,我只是在

中写了注解@Transactional
@Repository
@Transactional
public class AbstractHibernateDao<T extends Serializable> {

    private Class<T> clazz;

    @Autowired
    private SessionFactory sessionFactory;

这解决了我不使用 Flush 就无法删除或保存的问题。

【讨论】:

    猜你喜欢
    • 2012-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-28
    • 1970-01-01
    • 2016-12-27
    • 2021-12-04
    相关资源
    最近更新 更多