简体   繁体   English

Spring + Jboss7 @Transactional无法正常工作

[英]Spring + Jboss7 @Transactional Not working

I am upgrading my JBoss server from 5 to 7 and am now incorporating Spring 4. I am having some trouble using Spring's @Transactional annotation. 我正在将JBoss服务器从5升级到7,现在并入了@Transactional 。使用Spring的@Transactional批注时遇到了一些麻烦。 It does not appear to be working. 它似乎不起作用。 I am also trying to use a java based configuration file instead of an xml file (I believe I can get away without using any xml, but correct me if I am wrong). 我也尝试使用基于Java的配置文件而不是xml文件(我相信我可以不使用任何xml而逃脱,但是如果我错了,请更正我)。 The problem is that nothing is being saved in my db, leading me to believe that the @Transactional isn't working. 问题是我的数据库中没有保存任何内容,这使我相信@Transactional无法正常工作。 Here is my config file: 这是我的配置文件:

@Configuration
@ComponentScan
@EnableTransactionManagement
public class SpringBeanConfiguration {

@Bean
public FirstTestBean firstTestBean() {
    return new FirstTestBean();
}

@Bean
public TestService testService() {
    return new TestServiceImpl();
}

@Bean 
public SomethingDAO somethingDAO(){
    return new SomethingDAOImpl();
}

@Bean 
public GeneralDAO generalDAO(){
    return new GeneralDAOImpl();
}

Here is a test class with the @Transactional method: 这是带有@Transactional方法的测试类:

//@RequestScoped
@ManagedBean(name="firstTestBean")
@Component
public class FirstTestBean {

private EntityManager em;
private EntityManagerFactory emf;


@Transactional
public String transactionalTest() {
    //ApplicationContext context = new AnnotationConfigApplicationContext(SpringBeanConfiguration.class);
    Something something = new Something();
    getEntityManager().persist(something);
    return "dkljs";
}


public EntityManager getEntityManager() {
    if (em == null) {
        emf = Persistence.createEntityManagerFactory("xxx");
        em = emf.createEntityManager();
    }
    return em;
}

I am also using Hibernate 4, which is compatible with Spring. 我也在使用与Spring兼容的Hibernate 4。 I commented out the ApplicationContext because I have that running separately on the start up of JBoss. 我注释掉ApplicationContext是因为在JBoss启动时我要分别运行它。 I was using that earlier to access a bean, but I have since simplified things in order to get the @Transactional working and thus do not need it here. 我之前曾使用它来访问bean,但是为了使@Transactional工作,我已经简化了事情,因此在这里不需要它。 The @ComponentScan does not need parameters because these classes are in the same package. @ComponentScan不需要参数,因为这些类在同一程序包中。

Any help would be greatly appreciated. 任何帮助将不胜感激。 Thanks! 谢谢!

Updates 更新

I've made some of the changes suggested. 我已经提出了一些建议的更改。 Things appear to be moving in the right direction. 事情似乎朝着正确的方向发展。

Here are my updated files: 这是我的更新文件:

@ManagedBean(name="firstTestBean")
public class FirstTestBean {

public String getTestString() {     
    ApplicationContext context = new AnnotationConfigApplicationContext(SpringBeanConfiguration.class);
    TestService testService = context.getBean(TestService.class);       


    testService.transactionalTest();
    return "adfs";
}

public String test() {
    return "firstTestBean works";
}   
}

Note - some of these classes will be run outside of the Jboss application server as standalone applications, so for that reason, I am staying away from FacesContext when instantiating the TestService in FirstTestBean, as Spring beans work in standalone, but FacesContext beans do not. 注意-这些类中的某些类将作为独立应用程序在Jboss应用服务器之外运行,因此由于这个原因,我在FirstTestBean中实例化TestService时不使用FacesContext,因为Spring bean是独立运行的,而FacesContext bean不是。

@Component
@Transactional
public class TestServiceImpl implements TestService {

public GeneralDAO generalDAO;

//@Autowired
private EntityManager em;

//@Autowired
private EntityManagerFactory emf;


public TestServiceImpl(){}



public String transactionTest() {
    Something something = new Something();
    getEntityManager().persist(something);
    return "dkljs";
}

@autowired on the EntityManager and EntityManagerFactory did not work - I received an error saying No Qualified Bean of type EntityManager when it was annotated with the @autowired like suggested. EntityManager和EntityManagerFactory上的@autowired无法正常工作-我收到一条错误消息,提示使用@autowired进行注释时,提示EntityManager类型的没有合格Bean。

@Configuration
@ComponentScan
@EnableTransactionManagement
public class SpringBeanConfiguration implements     TransactionManagementConfigurer {



@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
    String hibernatePropsFilePath = "/[path]/hibernate.cfg.xml";
    File hibernatePropsFile = new File(hibernatePropsFilePath);

    org.hibernate.cfg.Configuration cfg = new org.hibernate.cfg.Configuration().configure(hibernatePropsFile);
    SessionFactory sessionFactory = cfg.buildSessionFactory();

    HibernateTransactionManager txManager = new HibernateTransactionManager(sessionFactory);
    txManager.setNestedTransactionAllowed(true);
    return txManager;
}

}

The error I am getting now is:Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.event.internalEventListenerProcessor': Initialization of bean failed ; 我现在遇到的错误是:原因:org.springframework.beans.factory.BeanCreationException:创建名称为“ org.springframework.context.event.internalEventListenerProcessor”的bean时出错:bean的初始化失败; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Injection of autowired dependencies failed; 嵌套的异常是org.springframework.beans.factory.BeanCreationException:创建名称为org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration的bean时出错:自动连接依赖项的注入失败; nested exception is org.hibernate.service.UnknownUnwrapTypeException: Cannot unwrap to requested type [javax.sql.DataSource] 嵌套的异常是org.hibernate.service.UnknownUnwrapTypeException:无法展开为请求的类型[javax.sql.DataSource]

I take it this means that the @Transactional is at least being recognized, but I'm having some issues getting this to work. 我认为这意味着至少@@@@@@@@@@@@@@@至少已被认可,但是我在使它工作时遇到了一些问题。 Any further advice would be greatly appreciated. 任何进一步的建议将不胜感激。

More Updates 更多更新

Found this article: http://www.baeldung.com/the-persistence-layer-with-spring-and-jpa#javaconfig 找到了这篇文章: http : //www.baeldung.com/the-persistence-layer-with-spring-and-jpa#javaconfig

and followed it. 然后跟着 My new config file: 我的新配置文件:

@Configuration
@ComponentScan
@EnableTransactionManagement
public class SpringBeanConfiguration { //implements  TransactionManagementConfigurer {

   @Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
      LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
      em.setDataSource(dataSource());
      em.setPackagesToScan(new String[] { "xxx.xxx.xxx" });

      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
      em.setJpaVendorAdapter(vendorAdapter);
   //   em.setJpaProperties(additionalProperties());

      return em;
   }

   @Bean
   public DataSource dataSource(){
      DriverManagerDataSource dataSource = new DriverManagerDataSource();
      dataSource.setDriverClassName("com.mysql.jdbc.Driver");
      dataSource.setUrl("jdbc:mysql://localhost:3306/jboss_test");
      dataSource.setUsername( "root" );
      dataSource.setPassword( "root" );
      return dataSource;
   }

   @Bean
   public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
      JpaTransactionManager transactionManager = new JpaTransactionManager();
      transactionManager.setEntityManagerFactory(emf);

      return transactionManager;
   }

   @Bean
   public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
      return new PersistenceExceptionTranslationPostProcessor();
   }

Good news is that I am no longer having deployment issues. 好消息是,我不再遇到部署问题。 The logging also suggests that my changes are having some effect on the server. 日志记录还表明我的更改对服务器有一定影响。 Unfortunately, nothing is being saved, so it is still not quite working. 不幸的是,什么都没有保存,因此仍然无法正常工作。

The first thing that draws my attention is the use of @Transactional and @Component on a ManagedBean. 引起我注意的第一件事是在ManagedBean上使用@Transactional和@Component。

JSF and Spring are definately made to work together but i never saw them used this way on many projects i was working on. JSF和Spring确实可以一起工作,但是我从未见过他们在我正在从事的许多项目中以这种方式使用它们。

Im not sure if that is the cause of your problems but please consider changing that. 我不确定这是否是造成您问题的原因,但请考虑将其更改。

I would do like this: 我会这样:

a) Define some service layer where you would wrap your calls with transactions and inject the JPA classes: a)定义一些服务层,您将在其中用事务包装呼叫并注入JPA类:

@Component
@Transactional
class Service{

   @Autowired
   private EntityManager em;

   @Autowired
   private EntityManagerFactory emf;

   public String serviceMethod(..){ .. }

}

b) Inject that to Jsf's ManagedBean while removing the unnecessary annotations: b)将其注入到Jsf的ManagedBean中,同时删除不必要的注释:

@ManagedBean(name="firstTestBean")
public class FirstTestBean {

  @ManagedProperty("#{service}")
  private Service service;

  public String transactionalTest() {
      return service.serviceMethod(); 
  }

}

Ok, so I finally got it (Check out my OP for all updates that led me to this point). 好的,所以我终于明白了(查看我的OP,了解所有导致我此刻的更新)。

Here's my final config file: 这是我的最终配置文件:

@Configuration
@ComponentScan
@EnableTransactionManagement
public class SpringBeanConfiguration { 

   @Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
      LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
      em.setPersistenceUnitName("myPersistenceContext");
      em.setDataSource(dataSource());
      em.setPackagesToScan(new String[] { "xxx.xxx.xxx" });

      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
      em.setJpaVendorAdapter(vendorAdapter);
   //   em.setJpaProperties(additionalProperties());

      return em;
   }

   @Bean
   public DataSource dataSource(){
      DriverManagerDataSource dataSource = new DriverManagerDataSource();
      dataSource.setDriverClassName("com.mysql.jdbc.Driver");
      dataSource.setUrl("jdbc:mysql://localhost:3306/jboss_test");
      dataSource.setUsername( "root" );
      dataSource.setPassword( "root" );
      return dataSource;
   }

   @Bean
   public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
      JtaTransactionManager transactionManager = new JtaTransactionManager();
     // transactionManager.setEntityManagerFactory(emf);

      return transactionManager;
   }

   @Bean
   public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
      return new PersistenceExceptionTranslationPostProcessor();
   }

So first, I added in 所以首先,我添加了

em.setPersistenceUnitName("myPersistenceContext");  

This gave me the error: 这给了我错误:

Spring IllegalStateException: A JTA EntityManager cannot use getTransaction() Spring IllegalStateException:JTA EntityManager无法使用getTransaction()

From here, I did some research ( Spring IllegalStateException: A JTA EntityManager cannot use getTransaction() ) 从这里开始,我做了一些研究( Spring IllegalStateException:JTA EntityManager不能使用getTransaction()

and changed 并改变了

JpaTransactionManager transactionManager = new JpaTransactionManager();

to

JtaTransactionManager transactionManager = new JtaTransactionManager();

Also, my persistence.xml file is: 另外,我的persistence.xml文件是:

    <persistence-unit name="myPersistenceContext">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:jboss/datasources/myDS</jta-data-source>
    <class>xxx.xxx.xxx.Something</class>    
    <exclude-unlisted-classes>false</exclude-unlisted-classes>

    <properties>
        <property name="hibernate.cache.use_second_level_cache" value="true" />
        <property name="hibernate.id.new_generator_mappings" value="false"/>
        <property name="hibernate.classloading.use_current_tccl_as_parent" value="false"/>
        <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" /> 
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.archive.autodetection" value="class, hbm" />
    </properties>
</persistence-unit>

Thanks to Maciej Kowalski for your help - you pushed me in the right direction. 感谢Maciej Kowalski的帮助-您将我推向正确的方向。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM