首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Spring/Hibernate @Transactional方法防止更新SQL

Spring/Hibernate @Transactional方法防止更新SQL
EN

Stack Overflow用户
提问于 2016-05-11 13:57:48
回答 2查看 1.3K关注 0票数 0
  • SpringV4.2.5发行版
  • Hibernate v5.1.0最后

我有一个Junit测试方法,它执行加载、更新属性并调用saveOrUpdate(bean)

奇怪的是,将@Transactional添加到方法签名会阻止执行update SQL (日志中没有生成SQL )。

删除@Transactional,生成update SQL并更新数据库。

代码语言:javascript
运行
复制
@Configuration
@EnableTransactionManagement
@PropertySource(
        {
            "classpath:jdbc.properties",
            "classpath:hibernate.properties"
        })
@ComponentScan(value = "com.savant.test.spring.donorservice.core.dao")
public class ApplicationContext {


    @Bean(destroyMethod = "close")
    @Autowired
    public DataSource dataSource() {

        // Hikari is a connection pool manager.
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setUsername(env.getProperty("jdbc.username"));
        dataSource.setPassword(env.getProperty("jdbc.password"));
        dataSource.setJdbcUrl(env.getProperty("jdbc.url"));
        dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
        dataSource.setIsolateInternalQueries(true);
        System.out.println(dataSource);

        dataSource.setConnectionTestQuery("SELECT count(*) from system.onerow");
        dataSource.setMaximumPoolSize(3);
        dataSource.setAutoCommit(false);

        return dataSource;
    }


    @Bean
    @Autowired
    public LocalSessionFactoryBean sessionFactory(DataSource datasouce) {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(datasouce);
        sessionFactory.setPackagesToScan(package_to_scan);
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
    }


    private Properties hibernateProperties() {
        Properties hibernateProperties = new Properties();
        hibernateProperties.put(hibernate_dialect, env.getProperty(hibernate_dialect));
        hibernateProperties.put(hibernate_current_session_context_class, env.getProperty(hibernate_current_session_context_class));
        hibernateProperties.put(hibernate_connection_autocommit, env.getProperty(hibernate_connection_autocommit));
        hibernateProperties.put(hibernate_format_sql, env.getProperty(hibernate_format_sql));
        hibernateProperties.put(hibernate_hbm2ddl_auto, env.getProperty(hibernate_hbm2ddl_auto));
        hibernateProperties.put(hibernate_show_sql, env.getProperty(hibernate_show_sql));
//        hibernateProperties.put(hibernate_connection_provider_class, env.getProperty(hibernate_connection_provider_class));
        return hibernateProperties;

    }


    @Bean
    @Autowired
    public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
        HibernateTransactionManager txManager = new HibernateTransactionManager(sessionFactory);
        return txManager;
    }

使用Netbeans的“数据库中的实体类”自动生成实体。

主实体与FetchType.EAGER有一对一的关系,与FetchType.EAGER有一对多的关系(下面是懒散的)。

测试方法如下所示。

代码语言:javascript
运行
复制
    @Test
    @Transactional
    public void c_testUpdateAddress1() {
        System.out.println("findById");
        String id = donorId;
        Donor donor = donorDao.findById(id);

        donor.setAbogrp(" O");

        for (DonorAddress da : donor.getDonorAddressCollection()) {
            da.setAddr1("Updated line");
            System.out.println(da.getDonorAddressPK().getAddrtype() + " " + da.getAddr1());
        }

        System.out.println("Update");

        Donor savedDonor = donorDao.save(donor);

    }    
  • 如果没有@Transactional,就会生成update SQL并更新数据库。
  • 使用@Transactional,更新SQL不会生成,也不会出现在日志中。没有例外,在我的Dao实现中跳过Save方法,一切看起来都很好。传入的bean具有正确的值(更新的字段值),返回的bean具有更新的字段值--只是没有生成SQL。 @覆盖公共捐助方保存(捐助方bean) { getSession().saveOrUpdate(bean);返回bean;}

我需要@Transactional的原因是允许向懒惰者提供地址。

如果没有@Transactional,由于异常“未能延迟初始化角色集合:无法初始化代理-没有会话”,我无法访问该地址。

EN

Stack Overflow用户

回答已采纳

发布于 2016-05-12 09:57:10

和预期的一样。

一旦检测到@Transactional方法并在该方法调用结束后立即提交该方法,事务就会启动。在测试的情况下是在测试方法结束之后。因此,在测试期间,您将看不到SQL。

此外,在基于Spring的测试中使用@Transactional时,默认情况下它将执行回滚而不是提交。请参阅参考指南中的这里关于默认值以及如何更改它的内容。

票数 1
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37164908

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档