Ich versuche Einheit in Repository zu speichern, aber es funktioniert nicht bei allen. Repository ist Autowired und in Laufzeit verwende ich saveAndFlush, um die Entity zu speichern. Ich benutze PostgreSQL. Über den Testmethoden habe ich Kommentare mit Erklärungen hinzugefügt, was vor sich geht. Ich habe erwartet, dass die Methode saveAndFlush funktionieren sollte, aber nicht. Ich kann den Grund nicht finden.Saving Einheit in Repository funktioniert nicht SPRING
@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-Schnittstelle
Datei@Repository
@Transactional
public interface MyRepository extends JpaRepository<MyData, Long> {}
MyData Datei
@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 Datei
@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();
}
...
}
Sie verwenden den falschen Transaktionsmanager. Für JPA benötigen Sie einen 'JpaTransactionManager', nicht den' HibernateTransactionManager'. warum auch mischen die 2. –
Stattdessen 2 Instanzen zu schaffen, nur einen 'LocalContainerEntityManagerFactory' erstellen und verwenden Sie die' 'HibernateJpaSessionFactoryBean' eine SessionFactory' zu belichten. Sie brauchen jetzt nur noch einen einzigen Transaktions-Fehler und können sowohl JPA als auch eine einfache Hibernate 'SessionFactory' verwenden, wenn Sie dies wirklich brauchen. –
Es hilft nicht, weil ich noch Transaction und commit beginnen muss, anstatt saveAndFlush für das Repository zu verwenden. Glauben Sie, es könnte Winterschlaf + postgresql spezifischen Fall sein? Kann es ohne Aufruf und Begehen getan werden? –