我有一个带有hibernate和jpa的spring-boot应用程序。尝试创建Foo
实体的新实例时(直接通过JpaRepository
或entityManager
),一切似乎都很好(没有错误,并且返回的实例的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
答案 0 :(得分:0)
问题出在默认的事务处理上(JPA存储库将其方法包装在@Transactional
中,所以无论我是否也这样做都没有关系)。通过创建“自定义”事务管理器bean来解决此问题。具体来说,Application.java
的丰富之处:
...
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());
return transactionManager;
}
...