1

我試圖配置一個自定義的Spring Data Repository來替換Spring的一些funcionality。春季數據 - 沒有交易正在進行

一切正常,在@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的註釋無處不在......包括從變化到RESOURCE_LOCAL JTA等...

+0

確保你沒有複製bean實例,你的配置也有一個錯誤,就是你的配置中有一個'EntityManager' bean,不要這樣做,因爲這會創建一個非彈簧託管的'EntityManager'實例。 –

+0

@ M.Deinum我已經仔細檢查了bean的重複情況......一切正常。關於'EntityManager',我需要注入Repository構造函數......唯一的方法是將'EntityManager'指定爲'@ Bean'。有沒有辦法做到這一點,而不創建一個明確的'EntityManager'?謝謝! –

+0

我會認爲這是一個設計缺陷。 'EntityManager'不是線程安全的,應該爲每個線程重新創建。通常情況下,spring會爲您處理這個問題(它爲使用Spring Transaction支持的EntityManager創建一個事務/線程安全代理)。你的實例沒有。 –

回答

4

使用時自定義JPA存儲庫,它擴展了Spring Data JPA,你需要一個工廠來創建這些存儲庫的實例。正如Spring Data JPA documentation中提到的那樣。

您當前的方法存在的問題是,您正在創建一個非彈簧管理的EntityManager實例。

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

通常被彈簧會爲EntityManager但在你的情況下,transaction aware proxy(由於@Bean方法)您的自定義實現得到一個簡單的EntityManager。創建一個工廠(如上所述)將解決這個問題。