如何解决将实体保存在资源库中不起作用SPRING
对于初学者,您实际上EntityManager
在不工作的测试用例中使用两种不同的方法:
-
EntityManager
通过Spring自动连接到您的测试中(这是单例,无论如何都应避免使用),其他是 -
EntityManager
由EntityManagerFactory
您的ApplicationConfiguration中的配置创建。
同时,EntityManagers
由于Hibernate的配置,您还将在上述2旁边运行另一个SessionSessionFactory
。另外,由于配置了HibernateTransactionManager
,所有由创建的事务@Transactional
都绑定到由存储库创建SessionFactory
和EntityManager
使用的Hibernate会话,因此肯定无法了解它。这就是为什么TransactionRequiredException
在您的存储库尝试保留数据时引发的原因。
要解决此问题,您可以考虑删除HibernateSessionFactory
,并将事务管理器切换为JpaTransactionManager
。然后,@Transactional
在您的存储库上将具有创建新事务并将其绑定EntityManager
到Spring已知的现有事务的作用。
值得一提的是,@Transactional
您的TestClass上的完全没有帮助,因为此类的实例没有由Spring实例化和管理。为了使这项工作有效,需要按如下所述提供正确的事务测试类配置:http ://docs.spring.io/spring/docs/current/spring-framework-
reference/html/testing.html。
希望这可以帮助。
解决方法
我正在尝试将实体保存在存储库中,但它根本不起作用。存储库是自动连线的,在运行时中,我使用saveAndFlush来保存实体。我正在使用PostgreSQL。在测试方法上方,我添加了注释并解释了发生的情况。我希望该方法saveAndFlush应该可以,但不能。我找不到原因。
@Transactional
public class TestClass{
@Autowired private MyRepository repository;
@Autowired private EntityManager entityManager;
// Working version
public void writingToRepositoryWorking() {
entityManager.getTransaction().begin();
entityManager.persist(new MyData(99));
entityManager.getTransaction().commit();
}
// not working and throws exception :
// TransactionRequiredException: no transaction is in progress
public void writingToRepositoryNotWorking() {
repository.saveAndFlush(new MyData(99));
}
// not working,no exception,no data in repository,// but auto generated ID is incremented
public void writingToRepositoryNotWorkingToo() {
repository.save(new MyData(99));
}
}
存储库接口文件
@Repository
@Transactional
public interface MyRepository extends JpaRepository<MyData,Long> {}
MyData文件
@Entity(name = "myData")
public class MyData {
@Id @GeneratedValue(strategy = GenerationType.AUTO) long id;
private int testValue;
public MyData() { }
public BugData(int testValue) {
this.testValue = testValue;
}
public long getId() {
return id;
}
public int getTestValue() {
return testValue;
}
}
ApplicationConfiguration文件
@Configuration
@EnableJpaRepositories("com.mypackage.app")
@EnableTransactionManagement
@PropertySource("classpath:application.properties")
@EnableWebMvc
class ApplicationConfiguration extends WebMvcConfigurationSupport {
@Value("${jdbc.url}") private String KEY_JDBC_URL;
@Value("${jdbc.username}") private String KEY_JDBC_USERNAME;
@Value("${jdbc.password}") private String KEY_JDBC_PASSWORD;
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
@Autowired
public LocalSessionFactoryBean sessionFactory(DataSource dataSource) {
LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setPackagesToScan("com.mypackage.app");
factory.setHibernateProperties(hibernateProperties());
return factory;
}
public Properties hibernateProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect","org.hibernate.dialect.PostgreSQLDialect");
properties.setProperty("hibernate.show_sql","true");
properties.setProperty("hibernate.hbm2ddl.auto","update");
return properties;
}
@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
return new HibernateTransactionManager(sessionFactory);
}
@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl(KEY_JDBC_URL);
dataSource.setUsername(KEY_JDBC_USERNAME);
dataSource.setPassword(KEY_JDBC_PASSWORD);
return dataSource;
}
@Bean
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan("com.mypackage.app");
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
em.setJpaProperties(hibernateProperties());
em.afterPropertiesSet();
return em.getObject();
}
@Bean
public EntityManager entityManager(EntityManagerFactory entityManagerFactory) {
return entityManagerFactory.createEntityManager();
}
...
}