Spring/Hibernate @Transactional on 方法阻止更新 SQL
Spring/Hibernate @Transactional on method prevents update SQL
- Spring v4.2.5 发布
- Hibernate v5.1.0.Final
我有一个执行加载、更新 属性 并调用 saveOrUpdate(bean)
的 Junit 测试方法。
它的行为很奇怪,因为将 @Transactional
添加到方法签名会阻止执行更新 SQL(日志中未生成 SQL)。
删除 @Transactional
并生成更新 SQL 并更新数据库。
@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 'Entity classes from Database' 自动生成的。
主要实体有
与 FetchType.EAGER 的一对一关系
与 FetchType.EAGER 的一对多关系(这是 LAZY - 请阅读下文)。
测试方法是这样的
@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
更新SQL生成和数据库
已更新。
与@Transactional
更新SQL不生成,不出现
在日志中。无一例外,跨过Save方法
在我的 Dao 实现中,一切看起来都很好。豆子传入
具有正确的值(更新的字段值),返回的 bean 具有
更新的字段值 - 只是没有生成 SQL。
@Override
public Donor save(Donor bean) {
getSession().saveOrUpdate(bean);
return bean;
}
我需要@Transactional
的原因是允许地址到LAZY。
没有 @Transactional
由于异常 "failed to lazily initialize a collection of role: could not initialize proxy - no Session"
,我无法以 LAZY 身份访问地址
- Spring v4.2.5 发布
- Hibernate v5.1.0.Final
我有一个执行加载、更新 属性 并调用 saveOrUpdate(bean)
的 Junit 测试方法。
它的行为很奇怪,因为将 @Transactional
添加到方法签名会阻止执行更新 SQL(日志中未生成 SQL)。
删除 @Transactional
并生成更新 SQL 并更新数据库。
@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 'Entity classes from Database' 自动生成的。
主要实体有 与 FetchType.EAGER 的一对一关系 与 FetchType.EAGER 的一对多关系(这是 LAZY - 请阅读下文)。
测试方法是这样的
@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
更新SQL生成和数据库 已更新。 与
@Transactional
更新SQL不生成,不出现 在日志中。无一例外,跨过Save方法 在我的 Dao 实现中,一切看起来都很好。豆子传入 具有正确的值(更新的字段值),返回的 bean 具有 更新的字段值 - 只是没有生成 SQL。@Override public Donor save(Donor bean) { getSession().saveOrUpdate(bean); return bean; }
我需要@Transactional
的原因是允许地址到LAZY。
没有 @Transactional
由于异常 "failed to lazily initialize a collection of role: could not initialize proxy - no Session"