spring5.3 mvc jpa hibernate5.6, сосуществование репозиториев и DAO hibernate (без загрузки spring)

#java #hibernate #spring-mvc #jpa #spring-data-jpa

#Ява #зимовать #весна-mvc #jpa #весна-данные-jpa

Вопрос:

Я переношу приложение из простого режима гибернации в JPA, поэтому мне нужно, чтобы многие DAO, которые у нас есть, работали, но также имели репозитории JPA для обработки некоторых таблиц в некоторых случаях использования.

У меня возникли проблемы с транзакциями. Я вызываю метод службы, который является @Транзакционным, с простого контроллера, но я получаю эту трассировку стека :

 javax.persistence.TransactionRequiredException: no transaction is in progress  at org.hibernate.internal.AbstractSharedSessionContract.checkTransactionNeededForUpdateOperation(AbstractSharedSessionContract.java:431) ~[hibernate-core-5.6.1.Final.jar:5.6.1.Final]  at org.hibernate.internal.SessionImpl.checkTransactionNeededForUpdateOperation(SessionImpl.java:3492) ~[hibernate-core-5.6.1.Final.jar:5.6.1.Final]  at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1408) ~[hibernate-core-5.6.1.Final.jar:5.6.1.Final]  at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1403) ~[hibernate-core-5.6.1.Final.jar:5.6.1.Final]  at org.springframework.orm.hibernate5.SessionFactoryUtils.flush(SessionFactoryUtils.java:113) ~[spring-orm-5.3.13.jar:5.3.13]  at org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:95) ~[spring-orm-5.3.13.jar:5.3.13]  at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:97) ~[spring-tx-5.3.13.jar:5.3.13]  at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:916) ~[spring-tx-5.3.13.jar:5.3.13]  at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:727) ~[spring-tx-5.3.13.jar:5.3.13]  at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711) ~[spring-tx-5.3.13.jar:5.3.13]  at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654) ~[spring-tx-5.3.13.jar:5.3.13]  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407) ~[spring-tx-5.3.13.jar:5.3.13]  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.13.jar:5.3.13]  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.13.jar:5.3.13]  at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.13.jar:5.3.13]  at com.sun.proxy.$Proxy144.myActualServiceMethod(Unknown Source) ~[?:?]  

Вот моя конфигурация JpaConfiguration :

 @Configuration @EnableJpaRepositories(  basePackages = {  "com.myapp.project.metier.domain.dao.repos"  } ) @EnableTransactionManagement @EnableJpaAuditing(auditorAwareRef = "jpaAuditorProvider") public class JpaConfig {  @Bean public AuditorAwarelt;Stringgt; jpaAuditorProvider() {  return new UsernameAuditorAware(); }  @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {  LocalContainerEntityManagerFactoryBean em  = new LocalContainerEntityManagerFactoryBean();  em.setDataSource(dataSource);  em.setPackagesToScan("com.myapp.project.metier.domain.entities");  em.setPersistenceUnitName("MyPersistenceUnit");  JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();  em.setJpaVendorAdapter(vendorAdapter);  em.setJpaProperties(additionalProperties());   return em; }  @Bean public DataSource dataSource() {  DriverManagerDataSource dataSource = new DriverManagerDataSource();  dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");  dataSource.setUrl("jdbc:mysql://127.0.0.1:3307/my_database");  dataSource.setUsername("root");  dataSource.setPassword("rootmdp");  return dataSource; }  @Bean public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {  final JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();  jpaTransactionManager.setEntityManagerFactory(entityManagerFactory);  return jpaTransactionManager; }  @Bean public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {  return new PersistenceExceptionTranslationPostProcessor(); }  final Properties additionalProperties() {   final Properties hibernateProperties = new Properties();  hibernateProperties.setProperty("hibernate.show_sql", "false");  hibernateProperties.setProperty("hibernate.format_sql", "false");  hibernateProperties.setProperty("hibernate.current_session_context_class",  "org.springframework.orm.hibernate5.SpringSessionContext");  // hibernateProperties.setProperty("hibernate.current_session_context_class", "thread");  // hibernateProperties.setProperty("hibernate.current_session_context_class",  // "jta");  // "org.springframework.orm.hibernate5.SpringSessionContext");  // hibernateProperties.setProperty("hibernate.transaction.jta.platform",  // "org.jadira.usertype.spi.jta.LocalTransactionManagerPlatform");  return hibernateProperties; }  // needed by the old DAOs that are not JPA repositories @Bean public SessionFactory sessionFactory(EntityManagerFactory entityManagerFactory) {  HibernateJpaSessionFactoryBean hibernateJpaSessionFactoryBean = new HibernateJpaSessionFactoryBean();  hibernateJpaSessionFactoryBean.setEntityManagerFactory(entityManagerFactory);  return hibernateJpaSessionFactoryBean.getObject();  // this causes an exception even though the documentation says it should be used  // org.springframework.orm.jpa.JpaSystemException: Could not obtain transaction-synchronized Session for current thread; nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread  /*return entityManagerFactory.unwrap(SessionFactory.class);*/ }  

}

Остальная часть моей конфигурации-это XML-файлы (это старое приложение Spring MVC).

Спасибо вам за вашу помощь

Комментарии:

1. Удалите LocalEntityManagerFactory и настройте LocalSessionFactory вместо этого. Начиная с hibernate 5.3 SessionFactory , он также является EntityManagerFactory . Так что вам нужен только один.

2. Я удалил LocalContainerEntityManagerFactoryBean компонент и добавил @Bean public LocalSessionFactoryBean sessionFactory(DataSource dataSource) { } , что теперь я получаю NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available ошибку, когда репозитории JPA пытаются создать экземпляр. Хотя в документации LocalSessionFactory говорится об очень интересных вещах, неясно, как это реализовать, я буду копать.

3. Переименуйте метод в entityManagerFactory или поместите оба имени компонента в @Bean аннотацию. Также убедитесь, что вы подключаете это к JpaTransactionManager (the SessionFactory ).

4. Я сделал это @Bean(name = {"entityManagerFactory", "sessionFactory"}) public LocalSessionFactoryBean sessionFactory(DataSource dataSource) , и это сработало ! Но с JpaTransactionManager помощью (того же, что и в исходном сообщении) код был запущен, но в БД ничего не было записано. поэтому я переключился на HibernateTransactionManager , и теперь он хорошо работает с транзакциями ! Спасибо вам 🙂 Не знаю, хорошо ли это» не использовать JpaTransactionManager «, хотя