我正在实现一个带有事务的服务层,所有配置都在Java配置中处理。 服务事务使用 JPA 存储库运行。 事务执行正常,SQL显示在日志中(如果我设置了休眠跟踪),但是没有数据插入数据库(Postgres)。 发生这种情况时,我什至没有收到异常。 解决此问题的最佳方法是什么? (简化的业务逻辑如下)
价值集服务.java
public interface ValueSetService {
void processValueSets(List<Code> codes);
}
ValueSetServiceImpl.java
@Service
public class ValueSetServiceImpl implements ValueSetService {
@Autowired
private ValueSetRepository valueSetRepository;
@Autowired
private CodeRepository codeRepository;
@Transactional
public void processValueSets(List<Code> codes)
{
for (Code code : codes)
{
codeRepository.save(code);
}
}
}
JpaConfig.java
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "org.package.repository")
@ComponentScan(basePackages = {"org.package.service"})
public class JpaConfig {
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager tm =
new JpaTransactionManager();
tm.setEntityManagerFactory(entityManagerFactory);
// tm.setDataSource(dataSource());
return tm;
}
@Bean
public PersistenceExceptionTranslationPostProcessor persistenceManager() {
return new PersistenceExceptionTranslationPostProcessor();
}
@Bean
public PropertyOverrideConfigurer propertyOverrideConfigurer() {
PropertyOverrideConfigurer config = new PropertyOverrideConfigurer();
config.setIgnoreResourceNotFound(true);
config.setLocation(new ClassPathResource("jpa.db.properties"));
return config;
}
@Bean(destroyMethod = "shutdown")
public HikariDataSource mainDataSource() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setUsername("user");
dataSource.setPassword("password");
dataSource.setJdbcUrl("jdbc:postgresql://localhost/dbname");
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setMaximumPoolSize(20);
return dataSource;
}
@Bean
public LazyConnectionDataSourceProxy dataSource() {
LazyConnectionDataSourceProxy dataSource = new LazyConnectionDataSourceProxy();
dataSource.setTargetDataSource(mainDataSource());
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setPersistenceUnitName("puName");
em.setDataSource(dataSource);
em.setPackagesToScan(new String[]{"org.package.model.**"});
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter
.setDatabasePlatform("org.hibernate.dialect.PostgreSQL9Dialect");
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
@Bean
public HibernateJpaSessionFactoryBean sessionFactory(EntityManagerFactory entityManagerFactory) {
HibernateJpaSessionFactoryBean sessionFactory = new HibernateJpaSessionFactoryBean();
sessionFactory.setEntityManagerFactory(entityManagerFactory);
return sessionFactory;
}
private Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect",
"org.hibernate.dialect.PostgreSQL9Dialect");
properties.setProperty("hibernate.generate_statistics", "false");
properties.setProperty("hibernate.show_sql", "false");
properties
.setProperty("hibernate.cache.use_second_level_cache", "true");
properties.setProperty("hibernate.cache.use_query_cache", "true");
properties.setProperty("hibernate.current_session_context_class",
"org.springframework.orm.hibernate4.SpringSessionContext");
properties.setProperty("hibernate.id.new_generator_mappings", "true");
properties.setProperty("hibernate.id.optimizer.pooled.prefer_lo",
"true");
properties.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory");
properties.setProperty("net.sf.ehcache.configurationResourceName", "/ehcache-model.xml");
return properties;
}
}
代码存储库.java
public interface CodeRepository extends JpaRepository<Code, Integer>, QueryDslPredicateExecutor<Code> {
}
代码.java
@Entity
@Table(name = "code", catalog = "dbname", schema = "application")
public class Code implements Cloneable, Serializable, IPojoGenEntity, ICode {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "codeCode_idGenerator")
@Basic( optional = false )
@Column( name = "code_id", nullable = false )
@SequenceGenerator(allocationSize=1, name = "codeCode_idGenerator", sequenceName = "dbname.application.code_id_seq", schema = "application", catalog = "dbname")
public Integer getId() {
return this.id;
}
@ManyToOne( cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY )
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
@Basic( optional = true )
@JoinColumn(name = "value_set_id", nullable = true )
public ValueSet getValueSet() {
return this.valueSet;
}
}
控制台中的休眠 SQL 输出示例
[28/04/2015 14:24:15] DEBUG insert into dbname.application.code (code_name, code_system_id, date_created, date_disabled, date_updated, description, user_created, user_updated, value_set_id, code_id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) (SQL)
Hibernate: insert into dbname.application.code (code_name, code_system_id, date_created, date_disabled, date_updated, description, user_created, user_updated, value_set_id, code_id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
[28/04/2015 14:24:15] TRACE binding parameter [1] as [VARCHAR] - [447422004] (BasicBinder)
[28/04/2015 14:24:15] TRACE binding parameter [2] as [INTEGER] - [39] (BasicBinder)
[28/04/2015 14:24:15] TRACE binding parameter [3] as [TIMESTAMP] - [Tue Apr 28 14:24:15 EDT 2015] (BasicBinder)
[28/04/2015 14:24:15] TRACE binding parameter [4] as [TIMESTAMP] - [null] (BasicBinder)
[28/04/2015 14:24:15] TRACE binding parameter [5] as [TIMESTAMP] - [Tue Apr 28 14:24:15 EDT 2015] (BasicBinder)
[28/04/2015 14:24:15] TRACE binding parameter [6] as [VARCHAR] - [Code name goes here] (BasicBinder)
[28/04/2015 14:24:15] TRACE binding parameter [7] as [INTEGER] - [null] (BasicBinder)
[28/04/2015 14:24:15] TRACE binding parameter [8] as [INTEGER] - [null] (BasicBinder)
[28/04/2015 14:24:15] TRACE binding parameter [9] as [INTEGER] - [666] (BasicBinder)
[28/04/2015 14:24:15] TRACE binding parameter [10] as [INTEGER] - [67310] (BasicBinder)
尝试添加 tm.afterPropertiesSet(); 如下所示或在 JpaTransactionManager 的构造函数中注入 entityManagerFactory。
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager tm = new JpaTransactionManager();
tm.setEntityManagerFactory(entityManagerFactory);
tm.afterPropertiesSet();
return tm;
}
该问题是由数据异常值引起的,该异常值在运行时基本上填满了事务日志(导致应用程序基本上停止)。 重构流程以提高性能。