0

我试图将spring xml配置转换为java配置。这通过XML配置完美工作。但是,如果我使用java配置初始化程序,则会引发以下异常。当它尝试运行JQL时会发生这种情况。应用程序虽然启动正确(所有JPA映射初始化)。InvalidDataAccessApiUsageException:执行更新/删除查询Spring XML到Java配置

org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query 
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:410) [spring-orm-4.1.5.RELEASE.jar:4.1.5.RELEASE] 
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:216) [spring-orm-4.1.5.RELEASE.jar:4.1.5.RELEASE] 
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417) [spring-orm-4.1.5.RELEASE.jar:4.1.5.RELEASE] 
at org.springframework.dao.support.ChainedPersistenceExceptionTranslat 

以下是我的持久化初始化类。阅读的位提示我这与交易没有正确启动有关。我已经将调试点放到了这些方法中的每一个,但是在服务器启动或以后的任何时候,transactionManager方法都不会被执行。我不知道我究竟做错了:(。完美持久时,通过初始化的persistence.xml相同的基于代码的作品。在道

访问该方法
public void updateById(final Long id) { 

     final String sqlQuery = "UPDATE testtable w SET w.LAST_ACCESSED = :date WHERE w.testtable_ID = :testid"; 
     final Query query = dao.createNativeQuery(sqlQuery); 
     query.setParameter("date", new Date()); 
     query.setParameter("testid", id); 
     query.executeUpdate(); 
    } 
+0

这些方法对于调试点......这些方法是豆宣言。所以这些只会在启动过程中被击中。关于例外情况,当您确切地知道这个错误时,我的意思是在做什么操作时,您是否也可以使用该代码。 – pvpkiran

+0

谢谢,据我所知,服务器启动调试模式,我打了其他两个bean初始化方法,但tx初始化方法。这就是为什么我怀疑我错过了事务初始化。编辑问题以显示JQL方法。再一次,这对xml配置有效。 – Charith

+0

在这个方法上使用'@Transactional'并试一试。 – pvpkiran

回答

1

最后,当发生

@Configuration 
@EnableTransactionManagement 
@EnableJpaRepositories(basePackages = "au.mypkg") 
public class DatabaseConfig { 


    @Bean(name = "dataSource") 
    @Primary 
    public DataSource dataSource() throws Exception { 
     Context ctx = new InitialContext(); 
     return (DataSource) ctx.lookup("java:jboss/datasources/mydb"); 
    } 

    @PersistenceContext(unitName = "persistenceUnit") 
    @Primary 
    @Bean(name = "entityManagerFactory") 
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws Exception { 
    .......... 

    @Primary 
    @Bean(name = "transactionManager") 
    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { 
     final JtaTransactionManager transactionManager = new JtaTransactionManager(); 
     transactionManager.setTransactionManagerName(JBOSS_TRANSACTION_MANANGER); 
     return transactionManager; 
    } 

错误想知道这是怎么回事,因为它没有达到调试点,EnableTransactionManagement强制为你自动配置事务,所以如果你的事务管理器配置了默认名字,在我的情况下,它不会尝试调用我的方法来配置事务。解决此问题的唯一方法是为transac使用不同的名称并将该ref作为enableJPARepository注释的参数传递。如果使用其中一个默认名称,则不会进行此调用。

@Primary 
@Bean(name = "myRealTransactionManager") 
public PlatformTransactionManager transactionManager() { 
    final JtaTransactionManager transactionManager = new JtaTransactionManager(); 
    transactionManager.setTransactionManagerName(JBOSS_TRANSACTION_MANANGER); 
    return transactionManager; 
} 

..然后

@EnableJpaRepositories(basePackages = "au.mypkg", transactionManagerRef = "myRealTransactionManager" 

的另一个问题是我所用过的setDataSource而不是setJtaDataSource上LocalContainerEntityManagerFatoryBean。

3

我遇到了一些问题,并通过在执行删除或更新的服务方法上添加@Transactional注释来解决问题。 在我的情况是,调用它通过我认为执行删除由JPQL这样的存储库方法的方法可以解决你的问题太多:

@Modifying  
@Query("delete from OtherPayment otherPayment " + 
     "where otherPayment.otherPaymentParam.id = :otherPaymentParamId")  
void deleteByOtherPaymentParamId(@Param("otherPaymentParamId") Long otherPaymentParamId); 
+0

它已经用@Transactional注解了。谢谢 – Charith