Spring 独立无法识别@Transactional
Spring Standalone not recognizing @Transactional
最近,我将 Spring 集成到我的 Jboss 应用程序中。我还准备了一个独立的应用程序,它将使用一些 Spring 服务 类。这是我的独立来源:
@Component
public class StandaloneTest {
public static ApplicationContext context;
public static void main(String[] args) {
context = new AnnotationConfigApplicationContext(StandaloneSpringBeanConfiguration.class);
StandaloneTest test = context.getBean(StandaloneTest.class);
System.out.println(context);
test.startProcess();
}
public StandaloneTest() {
}
/**
* Start the main process
*/
private void startProcess() {
run();
}
private void run() {
TestService testService = context.getBean(TestService.class);
testService.transactionalTest();
System.out.println("finished");
}
这是 TestService 的来源:
@Service
public class TestServiceImpl implements TestService {
public GeneralDAO generalDAO;
private EntityManager em;
private EntityManagerFactory emf;
public TestServiceImpl(){}
@Transactional
public void transactionalTest() {
Something something = new Something();
getEntityManager().persist(something);
}
public EntityManager getEntityManager() {
if (em == null) {
emf = Persistence.createEntityManagerFactory("xxx");
em = emf.createEntityManager();
}
return em;
}
}
当我 运行 在我的 Jboss 服务器中使用此方法时,@Transactional 注释按预期工作。但是,当我 运行 独立应用程序时,@Transactional 注释似乎被忽略了。我不知道为什么。
如果有人知道我需要做什么才能让它工作或有任何 ideas/comments,请分享。谢谢!
更新
这是我的配置文件:
@Configuration
@ComponentScan
@EnableTransactionManagement
public class StandaloneSpringBeanConfiguration {
@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){
JpaTransactionManager transactionManager = new JpaTransactionManager(emf);
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
更多更新
@Service
public class TestServiceImpl implements TestService {
public GeneralDAO generalDAO;
@PersistenceContext
private EntityManager em;
private EntityManagerFactory emf;
public TestServiceImpl(){}
@Transactional
public void transactionalTest() {
Something something = new Something();
em.persist(something);
}
}
这绝对让我朝着正确的方向前进。我现在收到此错误:没有可用的 JTA UserTransaction - 指定 'userTransaction' 或 'userTransactionName' 或 'transactionManager' 或 'transactionManagerName'
我无法找出原因,但问题是我选择的 transactionManager 吗?我在某个地方读到我需要独立使用 JOTM 或 Atomikos,但我认为 JOTM 不能用于 Spring 4 并且 Atomikos 要求我使用 Maven,这对我来说不是一个选项。使用 JTATransactionManager 给了我相同的结果。
工作解决方案
今天早上 JTA 错误似乎自行解决了。不确定发生了什么。然后我必须确保所有必要的包都被 LocalContainerEntityManagerFactoryBean 扫描,因为我得到一个 IllegalArgumentException Unknown Entity
配置
public class StandaloneSpringBeanConfiguration {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "xxx.xxx.xxx", "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();
}
服务Class
@Service
public class TestServiceImpl implements TestService {
public GeneralDAO generalDAO;
@PersistenceContext
private EntityManager em;
private EntityManagerFactory emf;
public TestServiceImpl(){}
@Transactional
public void transactionalTest() {
Something something = new Something();
em.persist(something);
}
}
交易工作正常,只是它们在您的设置中不起作用。这是因为您正在重新创建交易绑定 EntityManager
。
基本上,您 TestServiceImpl
的代码是有缺陷的。您应该删除 getEntityManager()
方法,并用 @PersistenceContext
注释 EntityManager
字段。
@Service
public class TestServiceImpl implements TestService {
public GeneralDAO generalDAO;
@PersistenceContext
private EntityManager em;
public TestServiceImpl(){}
@Transactional
public void transactionalTest() {
Something something = new Something();
em.persist(something);
}
}
这就是您所需要的。
最近,我将 Spring 集成到我的 Jboss 应用程序中。我还准备了一个独立的应用程序,它将使用一些 Spring 服务 类。这是我的独立来源:
@Component
public class StandaloneTest {
public static ApplicationContext context;
public static void main(String[] args) {
context = new AnnotationConfigApplicationContext(StandaloneSpringBeanConfiguration.class);
StandaloneTest test = context.getBean(StandaloneTest.class);
System.out.println(context);
test.startProcess();
}
public StandaloneTest() {
}
/**
* Start the main process
*/
private void startProcess() {
run();
}
private void run() {
TestService testService = context.getBean(TestService.class);
testService.transactionalTest();
System.out.println("finished");
}
这是 TestService 的来源:
@Service
public class TestServiceImpl implements TestService {
public GeneralDAO generalDAO;
private EntityManager em;
private EntityManagerFactory emf;
public TestServiceImpl(){}
@Transactional
public void transactionalTest() {
Something something = new Something();
getEntityManager().persist(something);
}
public EntityManager getEntityManager() {
if (em == null) {
emf = Persistence.createEntityManagerFactory("xxx");
em = emf.createEntityManager();
}
return em;
}
}
当我 运行 在我的 Jboss 服务器中使用此方法时,@Transactional 注释按预期工作。但是,当我 运行 独立应用程序时,@Transactional 注释似乎被忽略了。我不知道为什么。
如果有人知道我需要做什么才能让它工作或有任何 ideas/comments,请分享。谢谢!
更新
这是我的配置文件:
@Configuration
@ComponentScan
@EnableTransactionManagement
public class StandaloneSpringBeanConfiguration {
@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){
JpaTransactionManager transactionManager = new JpaTransactionManager(emf);
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
更多更新
@Service
public class TestServiceImpl implements TestService {
public GeneralDAO generalDAO;
@PersistenceContext
private EntityManager em;
private EntityManagerFactory emf;
public TestServiceImpl(){}
@Transactional
public void transactionalTest() {
Something something = new Something();
em.persist(something);
}
}
这绝对让我朝着正确的方向前进。我现在收到此错误:没有可用的 JTA UserTransaction - 指定 'userTransaction' 或 'userTransactionName' 或 'transactionManager' 或 'transactionManagerName'
我无法找出原因,但问题是我选择的 transactionManager 吗?我在某个地方读到我需要独立使用 JOTM 或 Atomikos,但我认为 JOTM 不能用于 Spring 4 并且 Atomikos 要求我使用 Maven,这对我来说不是一个选项。使用 JTATransactionManager 给了我相同的结果。
工作解决方案
今天早上 JTA 错误似乎自行解决了。不确定发生了什么。然后我必须确保所有必要的包都被 LocalContainerEntityManagerFactoryBean 扫描,因为我得到一个 IllegalArgumentException Unknown Entity
配置
public class StandaloneSpringBeanConfiguration {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "xxx.xxx.xxx", "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();
}
服务Class
@Service
public class TestServiceImpl implements TestService {
public GeneralDAO generalDAO;
@PersistenceContext
private EntityManager em;
private EntityManagerFactory emf;
public TestServiceImpl(){}
@Transactional
public void transactionalTest() {
Something something = new Something();
em.persist(something);
}
}
交易工作正常,只是它们在您的设置中不起作用。这是因为您正在重新创建交易绑定 EntityManager
。
基本上,您 TestServiceImpl
的代码是有缺陷的。您应该删除 getEntityManager()
方法,并用 @PersistenceContext
注释 EntityManager
字段。
@Service
public class TestServiceImpl implements TestService {
public GeneralDAO generalDAO;
@PersistenceContext
private EntityManager em;
public TestServiceImpl(){}
@Transactional
public void transactionalTest() {
Something something = new Something();
em.persist(something);
}
}
这就是您所需要的。