java - Spring + Jboss7 @Transactional 不工作

标签 java spring hibernate jsf jboss

我正在将 JBoss 服务器从 5 升级到 7,现在正在合并 Spring 4。我在使用 Spring 的 @Transactional 注释时遇到了一些问题。它似乎不起作用。我还尝试使用基于java的配置文件而不是xml文件(我相信我可以在不使用任何xml的情况下逃脱,但如果我错了请纠正我)。问题是我的数据库中没有保存任何内容,这让我相信 @Transactional 不起作用。这是我的配置文件:

@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();
}

这是一个带有 @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;
}

我还使用 Hibernate 4,它与 Spring 兼容。我注释掉了 ApplicationContext 因为我在 JBoss 启动时单独运行它。我之前使用它来访问 bean,但后来我简化了一些事情,以便让 @Transactional 工作,因此这里不需要它。 @ComponentScan 不需要参数,因为这些类位于同一个包中。

任何帮助将不胜感激。谢谢!

更新

我已经做出了一些建议的更改。事情似乎正在朝着正确的方向发展。

这是我更新的文件:

@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";
}   
}

注意 - 其中一些类将作为独立应用程序在 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";
}

EntityManager 和 EntityManagerFactory 上的 @autowired 不起作用 - 当按照建议使用 @autowired 进行注释时,我收到一条错误,提示 No Qualified 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;
}

}

我现在遇到的错误是:由 org.springframework.beans.factory.BeanCreationException 引起:创建名称为“org.springframework.context.event.internalEventListenerProcessor”的 bean 时出错:bean 初始化失败 ;嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名称为“org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration”的bean时出错: Autowiring 依赖项注入(inject)失败;嵌套异常是 org.hibernate.service.UnknownUnwrapTypeException:无法解包到请求的类型 [javax.sql.DataSource]

我认为这意味着 @Transactional 至少被识别,但我在使其正常工作时遇到了一些问题。任何进一步的建议将不胜感激。

更多更新

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

然后就跟着它了。我的新配置文件:

@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();
   }

好消息是我不再遇到部署问题。日志记录还表明我的更改对服务器产生了一些影响。不幸的是,没有保存任何内容,因此它仍然无法正常工作。

最佳答案

引起我注意的第一件事是在 ManagedBean 上使用 @Transactional 和 @Component。

JSF 和 Spring 肯定是一起工作的,但我从未见过它们在我正在从事的许多项目中以这种方式使用。

我不确定这是否是导致您出现问题的原因,但请考虑更改它。

我会这样做:

a) 定义一些服务层,您可以在其中使用事务包装调用并注入(inject) JPA 类:

@Component
@Transactional
class Service{

   @Autowired
   private EntityManager em;

   @Autowired
   private EntityManagerFactory emf;

   public String serviceMethod(..){ .. }

}

b) 将其注入(inject) Jsf 的 ManagedBean,同时删除不必要的注释:

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

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

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

}

关于java - Spring + Jboss7 @Transactional 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41752258/

相关文章:

spring - Spring 的 DefaultMessageListenerContainer 中 taskExecutor 属性的用途

java - 为什么在 JPA 2/Hibernate 中使用共享主键时实体需要可序列化?

java - 序列化draw2d LayeredPane

java - 将第一个 CompletableFuture 的结果传递给链上的其他 CompletableFuture

java - 对链表进行排序

spring - 在 netbeans ide 中运行 spring 测试

java - 在 Spring Boot 中使用 web.xml 安全约束

PostgreSQL/JPA - 在 import.sql 文件中导入函数?

java - 强制 Hibernate 在删除并重新创建数据库后创建表

java - JMapViewer居中