Spring Hibernate JPA - @Transactional不插入数据(Postgres)

时间:2015-04-28 17:36:03

标签: java spring hibernate postgresql jpa

我正在使用事务实现服务层,所有配置都在Java配置中处理。服务事务使用JPA存储库运行。事务执行正常,SQL显示在日志中(如果我设置了Hibernate跟踪),但没有数据插入到数据库中(Postgres。)当发生这种情况时我甚至都没有收到异常。解决这个问题的最佳方法是什么? (以下简化的业务逻辑)

ValueSetService.java

12/15

ValueSetServiceImpl.java

public interface ValueSetService {
    void processValueSets(List<Code> codes);
}

JpaConfig.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);
        }
    }

}

CodeRepository.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;
    }
}

Code.java

public interface CodeRepository extends JpaRepository<Code, Integer>, QueryDslPredicateExecutor<Code> {

}

控制台中的示例Hibernate SQL输出

@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;

    }

}

2 个答案:

答案 0 :(得分:0)

尝试添加tm.afterPropertiesSet();如下所示,或者在JpaTransactionManager的构造函数中注入entityManagerFactory。

@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
    JpaTransactionManager tm = new JpaTransactionManager();
    tm.setEntityManagerFactory(entityManagerFactory);
    tm.afterPropertiesSet();
    return tm;
}

答案 1 :(得分:0)

问题是由于数据异常值导致在运行时基本上填满了事务日志(导致应用程序基本停止。)重构流程以提高性能。