【问题标题】:@Transactional doesn't open Hibernate Transaction@Transactional 不打开休眠事务
【发布时间】:2015-02-09 13:57:57
【问题描述】:

我在 beans.xml 中声明了 Spring Beans:

<context:annotation-config />   
<context:component-scan base-package="com.pack"/>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
              class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="sessionFactory"/>
     <property name="dataSource" ref="dataSource"></property>
</bean>

dataSource 和 sessionFactory bean:

@Bean(name = "dataSource")
    public DriverManagerDataSource dataSource() {
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setUsername(userName);
        ds.setPassword(password);
        ds.setDriverClassName(driverName);
        ds.setUrl(url);
        return ds;
    }

@Bean(name = "sessionFactory")
    public LocalSessionFactoryBean localSessionFactoryBean() {
        LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
        factory.setDataSource(dataSourceConfiguration.dataSource());

        Properties props = new Properties();
        props.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
        props.put("hibernate.hbm2ddl.auto", "update");
        props.put("hibernate.current_session_context_class", "thread");
        factory.setHibernateProperties(props);
        factory.setMappingResources("com/pack/Item.hbm.xml");

        return factory;
    }

如果我分别使用 sessionFactory 和 dataSource bean,它们运行良好。 A 也有 DAO 类:

@Repository(value = "itemDaoHibernateImpl")
public class ItemDaoHibernateImpl implements ItemDao {

    @Resource(name = "sessionFactory")
    private SessionFactory factory;

    public void setFactory(SessionFactory factory) {
        this.factory = factory;
    }

    public Session session() {
        return factory.getCurrentSession();
    }

    @Override
    public void create(Item item) {
        session().save(item);
    }

我不打开会话,因为我想强制 Spring 执行此操作。我有带有方法的服务类:

@Override
@Transactional
public void create(Item item) {
    dao.create(item);
}

当我调用它时,我有例外:

org.hibernate.HibernateException: save is not valid without active transaction

我已经像this tutorial 所说的那样做了。我的错在哪里?

【问题讨论】:

  • 你注入调用create(Item item)的类吗? (我投赞成票,所以你有足够的声誉在 cmets 中回答)
  • 您能否提供sessionFactory 的实现?
  • 我当然愿意。我已经更新了我的问题。看看我的 dataSource 和 sessionFactory bean
  • @Transactional 使用 Spring AOP 应用(默认使用 JDK 代理),您的服务是否实现接口?是在声明 create 方法的服务类外部调用 create 吗?

标签: java spring hibernate transactions


【解决方案1】:

尝试从您的 sessionFactory 配置中删除 props.put("hibernate.current_session_context_class", "thread")。当您使用 Spring 托管事务时,您不需要它。让我知道这是否有效。

【讨论】:

  • 谢谢!!杰出的!有用!但是,如果我不确定该参数,spring 将如何创建一个新会话? spring 将如何通过每个请求创建新会话?我该怎么办?
  • SessionFactory 是由 Spring 使用给定的 dataSource 创建的,并从连接池中获取其 DB 连接。我们通过 SessionFactory.getCurrentSession() 获得一个 Hibernate 会话。然后开始事务,执行工作,然后提交()或回滚(),最后关闭连接(连接对象将返回到池中)。当我们停止应用程序或关闭服务器时,Hibernate 会话工厂将被销毁/关闭。
  • 我应该在这个参数中输入什么值?
  • 不要使用 @Transactional 为 Spring 托管事务设置任何内容。
  • Spring 拥有来自休眠的CurrentSessionContext 接口的its own implementation。这是默认设置的,一旦你开始使用 current_session_context_class 属性就不会出现这种情况,因此作为使用 Spring 时的一般经验法则,不要设置该属性。
【解决方案2】:

我之前遇到过这种情况是因为 Spring 是使用 CGLib 还是 Javassist 来增强您的类以提供事务性。如果我没记错的话,如果你只有 Javassist,那么 Spring 需要在其上创建代理以实现 Transactional 注释的类必须实现一个接口。

【讨论】:

    猜你喜欢
    • 2014-07-26
    • 2018-12-31
    • 2011-06-13
    • 2017-06-19
    • 2017-09-04
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    相关资源
    最近更新 更多