Java 弹簧&x2B;Jboss7@Transactional不工作
我正在将我的JBoss服务器从5升级到7,现在加入Spring4。我在使用Spring的Java 弹簧&x2B;Jboss7@Transactional不工作,java,spring,hibernate,jsf,jboss,Java,Spring,Hibernate,Jsf,Jboss,我正在将我的JBoss服务器从5升级到7,现在加入Spring4。我在使用Spring的@Transactional注释时遇到一些问题。它似乎不起作用。我还尝试使用基于java的配置文件而不是xml文件(我相信我可以不使用任何xml,但如果我错了,请纠正我)。问题是数据库中没有保存任何内容,这让我相信@Transactional不起作用。这是我的配置文件: @Configuration @ComponentScan @EnableTransactionManagement public clas
@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;
}
我也在使用Hibernate4,它与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,因为SpringBean在standalone中工作,但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-like注释EntityManager类型的合格Bean时,我收到一个错误,说没有合格的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时出错:
自动连线依赖项的注入失败;嵌套异常为org.hibernate.service.UnknownUnwrapTypeException:无法展开为请求的类型[javax.sql.DataSource]
我认为这意味着@Transactional至少被认可了,但我在如何让它正常工作方面遇到了一些问题。如有任何进一步建议,将不胜感激
更多更新
找到这篇文章:
然后跟着它走。我的新配置文件:
@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();
}
@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();
}
好消息是我不再有部署问题。日志还表明我的更改对服务器产生了一些影响。不幸的是,没有保存任何内容,因此它仍然不太起作用 引起我注意的第一件事是在ManagedBean上使用@Transactional和@Component JSF和Spring绝对是为了协同工作而设计的,但我从未见过它们以这种方式用于我所从事的许多项目 我不确定这是否是你的问题的原因,但请考虑改变它。 我想这样做: a)定义一些服务层,您可以在其中使用事务包装调用并注入JPA类:
@Component
@Transactional
class Service{
@Autowired
private EntityManager em;
@Autowired
private EntityManagerFactory emf;
public String serviceMethod(..){ .. }
}
b)将其注入Jsf的ManagedBean,同时删除不必要的注释:
@ManagedBean(name="firstTestBean")
public class FirstTestBean {
@ManagedProperty("#{service}")
private Service service;
public String transactionalTest() {
return service.serviceMethod();
}
}
好的,我终于明白了(请查看我的OP,查看所有导致我达到这一点的更新)
这是我的最终配置文件:
@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();
}
@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();
}
所以首先,我加入了
em.setPersistenceUnitName("myPersistenceContext");
这给了我一个错误:
Spring IllegalStateException:JTA EntityManager无法使用getTransaction()
从这里开始,我做了一些研究()
改变
JpaTransactionManager transactionManager = new JpaTransactionManager();
到
另外,我的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>
org.hibernate.ejb.HibernatePersistence
java:jboss/datasources/myDS
xxx.xxx.xxx.什么
假的
感谢Maciej Kowalski的帮助-你把我推向了正确的方向 我本来是这样的,但我试着简化它,只是想看看我是否能做点什么……我会把更改恢复到我原来做的,然后试试你说的。我会发布更新。谢谢你的帮助。做了一些更新。很抱歉反应太晚-我想先稍微修改一下。就我所记得的,将JPA、Hibernate和Spring绑定在一起的方式有点不同(至少我使用了不同的配置)。尝试注入SessionFactory而不是EntityManagerFactory,看看它是否有效。如果您真的需要坚持使用JPA,那么我将给您一些配置链接。我尝试了自动连接Sessionfactory,但得到了与EntityManagerFactory相同的错误。坚持JPA绝对是理想的选择。配置链接一定会很感激。谢谢找到了一篇有帮助的文章-我在上面列出了一些改动,但仍然不太清楚我需要做什么