【问题标题】:Spring Data CrudRepository on java based configuration - EntityManager - no transaction is in progress基于 java 的配置上的 Spring Data CrudRepository - EntityManager - 没有正在进行的事务
【发布时间】:2014-11-05 11:15:10
【问题描述】:

我已阅读我相信尝试过所有关于此的帖子,但没有找到正确答案的运气。 我在我的 spring mvc 项目中使用基于 java 的配置,并想尝试 Spring CrudRepository,以摆脱 DAO,这就是整个地狱崩溃的时候: 在持续后刷新时以“没有正在进行的事务”开始: - 尝试将 @Transactional 添加到方法中 - 此处发现的所有变体均无效 - 尝试更改配置,但由于它是基于 java 的,所以大多数答案都是基于 xml 的。也没有运气。 所以最后我不得不问:

如何配置我的项目以使 CrudRepository 持久化,或者如何使用 java 配置创建 Spring EntityManager。

这是我的配置文件的最后一个版本:

@Configuration
@ComponentScan(basePackages = { "ba.fit.vms" })
@ImportResource(value = "classpath:spring-security-context.xml")
@EnableTransactionManagement
@EnableJpaRepositories
public class AppConfig {

    @Bean
    public static PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() {
        PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
        ppc.setLocation(new ClassPathResource("/persistence.properties"));
        return ppc;
    }


    // Security Configuration
    @Bean
    public KorisnickiServis korisnickiServis(){
        return new KorisnickiServis();
    }

    @Bean
    public TokenBasedRememberMeServices rememberMeServices() {
        return new TokenBasedRememberMeServices("remember-me-key", korisnickiServis());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new StandardPasswordEncoder();
    }

    // Jpa Configuration
    @Value("${dataSource.driverClassName}")
    private String driver;
    @Value("${dataSource.url}")
    private String url;
    @Value("${dataSource.username}")
    private String username;
    @Value("${dataSource.password}")
    private String password;
    @Value("${hibernate.dialect}")
    private String dialect;
    @Value("${hibernate.hbm2ddl.auto}")
    private String hbm2ddlAuto;   

    @Bean
    public DataSource configureDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean configureEntityManagerFactory() {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(configureDataSource());
        entityManagerFactoryBean.setPackagesToScan("ba.fit.vms");
        entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());

        Properties jpaProperties = new Properties();
        jpaProperties.put(org.hibernate.cfg.Environment.DIALECT, dialect);
        jpaProperties.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, hbm2ddlAuto);
        //jpaProperties.put(org.hibernate.cfg.Environment.SHOW_SQL, true);
        entityManagerFactoryBean.setJpaProperties(jpaProperties);

        return entityManagerFactoryBean;
    }


    @Bean
    public PlatformTransactionManager transactionManager() {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(configureEntityManagerFactory().getObject());

        return transactionManager;
    }

}

我尝试了多种变体,但总是收到相同的“没有正在进行的交易”错误。 此外,只需一瞥回购: LokacijaRepository:

@Transactional
public interface LokacijaRepository extends CrudRepository<Lokacija, Long> {

}

还有 LokacijaRepositoryImpl:

@Repository
public class LokacijaRepositoryImpl implements LokacijaRepository {

    protected static Logger logger = Logger.getLogger("repo");
    @PersistenceContext // tried this as well(type= PersistenceContextType.EXTENDED)
    private EntityManager entityManager;


    @Override
    @Transactional// tried number of variations here as well, like REQUIRED...
    public <S extends Lokacija> S save(S entity) {
        logger.debug("trying to save!");
        try {
            entityManager.persist(entity);
            entityManager.flush();
            return entity;
        } catch (Exception e) {
            logger.debug("error: "+ e.toString());
            return null;
        }

    }

如果您需要其他任何东西来帮助我解决这个问题,请告诉我。

【问题讨论】:

  • 如果你使用的是 Spring Data JPA(似乎是这样),为什么你有LokacijaRepositoryImpl
  • 我想我虽然这是必须的?我该怎么做?
  • 我不敢相信!!!我删除了 LokacijaRepositoryImpl 并收到此错误:“没有定义名为 'entityManagerFactory' 的 bean”。我查看了文档,它说使用默认名称:'entityManagerFactory'。我将方法的名称从 configureEntityManagerFactory 更改为 entityManagerFactory 就是这样!!!
  • 很高兴知道!您认为您还是我应该将其添加为答案?您认为它会对未来的读者有所帮助吗?
  • 回答它不会有什么坏处。关于基于注释的配置的信息不足,因此应予以识别。把答案放在这里,我会把它标记为已回答!

标签: java spring-mvc transactions spring-data entitymanager


【解决方案1】:

问题是您正在尝试创建 LokacijaRepository(在 LokacijaRepositoryImpl 中)的实现,而 Spring Data JPA(您已配置)正在尝试执行相同操作。

你需要做的是:

  1. 完全删除LokacijaRepositoryImpl
  2. configureEntityManagerFactory 更改为entityManagerFactory entityManagerFactoryRef=configureEntityManagerFactory 添加到@EnableJpaRepositories

【讨论】:

  • 这正是我所做的。删除了存储库的实现,并将 configureEntityManagerFactory 重命名为 entityManagerFactory,它就像一个魅力!我还没有测试添加它,但我以后可能会。
猜你喜欢
  • 2015-05-04
  • 2013-12-09
  • 2012-02-10
  • 2015-05-11
  • 2016-03-26
  • 2017-12-30
  • 2018-11-11
  • 2017-03-04
  • 1970-01-01
相关资源
最近更新 更多