1

Я пытаюсь настроить пользовательский репозиторий данных Spring, чтобы заменить некоторую функциональность весны.Данные Spring - транзакция не выполняется

Все отлично работает в @Repository интерфейсов, но в @Repository реализации, я не получил нет сделки.

Ошибка:

javax.persistence.TransactionRequiredException: no transaction is in progress 

Вот мой файл конфигурации:

@Configuration 
@ComponentScan ({"com.app.core.authentication", "com.app.core.service","com.app.core.repository"}) 
@EnableTransactionManagement 
@EnableJpaRepositories(basePackages = {"com.app.core.repository"}) 
public class AppCoreConfiguration implements TransactionManagementConfigurer { 

@Bean 
public DataSource dataSource() { 
    DataSource dataSource = null; 
    try { 
     Context ctx = new InitialContext(); 
     dataSource = (DataSource) ctx.lookup("java:jboss/postgresDS"); 
    } catch (NamingException e) { 
     e.printStackTrace(); 
    } 
    return dataSource; 
} 

@Bean 
public EntityManagerFactory entityManagerFactory() { 

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
    vendorAdapter.setGenerateDdl(true); 
    vendorAdapter.setShowSql(true); 

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); 
    factory.setJpaVendorAdapter(vendorAdapter); 
    factory.setPackagesToScan("com.app.core.entity"); 
    factory.setDataSource(dataSource()); 
    factory.afterPropertiesSet(); 

    return factory.getObject(); 
} 

@Bean 
public PlatformTransactionManager transactionManager() { 

    JpaTransactionManager txManager = new JpaTransactionManager(); 
    txManager.setEntityManagerFactory(entityManagerFactory()); 
    txManager.setDataSource(dataSource()); 
    return txManager; 
} 


@Bean 
public HibernateExceptionTranslator hibernateExceptionTranslator(){ 
    return new HibernateExceptionTranslator(); 
} 

@Bean 
public EntityManager entityManger() { 
    return entityManagerFactory().createEntityManager(); 
} 

@Override 
public PlatformTransactionManager annotationDrivenTransactionManager() { 
    return transactionManager(); 
} 

}

И мой репозиторий класс:

@Repository 
public class ClientRepository extends JPABaseRepository<String, Client> implements IClientRepository { 

@Autowired 
public ClienteRepository (EntityManager em) { 
    super(Cliente.class, em); 
} 

@Override 
@Transactional 
public Cliente save(Client client) { 
    return saveAndFlush(client); 
} 
} 

И интерфейс:

@NoRepositoryBean 
public interface IClientRepository extends IJPABaseRepository<String, Client> { 
    ... 
} 

Знал ли человек, почему этот пользователь: @Repository Класс не получил менеджера по транзакции? Это странно, потому что все интерфейсы не реализованы отлично работает ...

я уже пытался поставить @Transaction «s аннотацию везде ... включая изменения от RESOURCE_LOCAL до JTA и так далее ...

+0

Убедитесь, что вы не дублируете экземпляры bean-компонентов, а также неправильная конфигурация в том, что у вас есть компонент 'EntityManager' в вашей конфигурации, не делайте этого, так как это создаст экземпляр EntityManager, не связанный с пружиной , –

+0

@ M.Deinum Я дважды проверял дублирование фасоли ... все в порядке. О 'EntityManager', мне нужно ввести в конструктор Repository ... единственный способ сделать это - указать' EntityManager' как '@ Bean'. Есть ли способ сделать это без создания явного «EntityManager»? Благодаря! –

+0

Я бы счел это ошибкой дизайна. «EntityManager» не является потокобезопасным и должен быть воссоздан для каждого потока. Обычно пружина обрабатывает это для вас (он создает прокси-протокол/потокобезопасный прокси для «EntityManager», который использует поддержку Spring Transaction). У вашего экземпляра нет. –

ответ

4

При использовании пользовательские репозитории JPA, которые расширяют Spring Data JPA, вам нужна фабрика для создания экземпляров этих репозиториев. Как упоминалось в Spring Data JPA documentation.

Проблема с вашим текущим подходом заключается в том, что вы создаете экземпляр EntityManager, не связанный с весной.

@Bean 
public EntityManager entityManger() { 
    return entityManagerFactory().createEntityManager(); 
} 

Обычно Spring создает transaction aware proxy для EntityManager, но в вашем случае (из-за методом @Bean) пользовательская реализация получает простую EntityManager. Создание фабрики (как упоминалось выше) позволит решить эту проблему.

Смежные вопросы