EntityManager无法正确持久

时间:2019-04-04 14:44:45

标签: java hibernate spring-boot jpa

我有一个带有hibernate和jpa的spring-boot应用程序。尝试创建Foo实体的新实例时(直接通过JpaRepositoryentityManager),一切似乎都很好(没有错误,并且返回的实例的id递增),但是这些实例将全部保存到db中,也不会在查询到orm时返回(由JpaRepository.findAll()entityManager.find(FooImpl.class, id)都不返回)

我尝试调用saveAndFlush的方法,而不是save的{​​{1}}->引发错误(无事务)

我尝试手动刷新JpaRepository->相同的错误。

我检查了entityManager的flushMode->它是'AUTO'

我尝试直接使用entityManager查询实例->找不到实例

我尝试使用entityManager.find(CourseImpl.class, id)注释服务方法->没有区别

我的实体:

@Transactional

我的@Entity @Table(name = "foo") public class FooImpl implements Foo{ @Id @GeneratedValue private Long id; @Column private String someOtherValue; ... @Override public Long getId() { return id; } @Override public void setId(Long id) { this.id = id; } }

Application.java

服务中的相关方法:

@SpringBootApplication
@EnableJpaRepositories
@EnableTransactionManagement
@EnableJpaAuditing
public class Application extends SpringBootServletInitializer implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")
    public javax.sql.DataSource primaryDataSource() {

        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUsername("username");
        dataSource.setPassword("n0tRea1Pasw0rd");
        dataSource.setUrl("jdbc\\:mysql\\://localhost\\:3306/bar");
        dataSource.setSchema("bar");

        return dataSource;
    }

    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {

        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorCustomAdapter());
        entityManagerFactoryBean.setDataSource(primaryDataSource());
        entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
        entityManagerFactoryBean.setPackagesToScan(new String[] { "org.baeldung.persistence.model", "cz.mycompany.bar.domain"});

        Properties properties = new Properties();
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
        properties.setProperty("hibernate.hbm2ddl.auto", "update");

        entityManagerFactoryBean.setJpaProperties(properties);

        return entityManagerFactoryBean;
    }

    public static void main(String[] args) {
        applicationContext = SpringApplication.run(Application.class, args);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        Application.applicationContext = applicationContext;
    }
}

我的... @Override public Foo create(){ return fooRepository.save(new FooImpl()); } @Override public List<Foo> findAll() { return Lists.newArrayList(fooRepository.findAll()); } ...

fooRepository

我还尝试了以下方法的自定义实现:

@RepositoryRestResource(collectionResourceRel = "foo", path = "foo")
public interface FooRepository extends JpaRepository<FooImpl, Long> {}

当前状态是升级到Java 11的结果,所以我包括了public class FooRepositoryImpl implements FooRepository { @PersistenceContext private EntityManager entityManager; ... @Override public <S extends FooImpl> S save(S entity) { entityManager.persist(entity); // entityManager.flush(); this threw error return entity; } ... } 的相关部分:

pom.xml

1 个答案:

答案 0 :(得分:0)

问题出在默认的事务处理上(JPA存储库将其方法包装在@Transactional中,所以无论我是否也这样做都没有关系)。通过创建“自定义”事务管理器bean来解决此问题。具体来说,Application.java的丰富之处:

...
    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());
        return transactionManager;
    }
...