同事们,您能帮助我@Transactional
注释吗?我的目标是将数据库事务管理传递给Spring,并在当前情况下将数据保存在数据库中。
我在DAO类中有两种方法:
@Component
public class OdValuesDAO
{
static final Logger LOG =
Logger.getLogger(OdValuesDAO.class.getName());
@Autowired
// @PersistenceContext(unitName = "PersistenceUnit")
@Qualifier("emR")
private EntityManager em;
public void addOdValue (OdValuesEntity odValuesEntity) {
LOG.info(odValuesEntity.toString());
//EntityTransaction tx = em.getTransaction(); Data will be saved DB if uncomment this code.
///tx.begin();
//LOG.info(tx.isActive());
em.persist(odValuesEntity);
///tx.commit();
}
public List<OdValuesEntity> getShare (OdValuesEntity odValuesEntity) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<OdValuesEntity> criteriaQuery = cb.createQuery(OdValuesEntity.class);
Root<OdValuesEntity> entityRoot = criteriaQuery.from(OdValuesEntity.class);
Predicate criteria = cb.conjunction();
if (odValuesEntity.getId() != null) .........
criteriaQuery.where(criteria);
List<OdValuesEntity> result = em.createQuery(criteriaQuery).getResultList();
return result;
}
和服务方法:
@Component
public class OdValuesService {
static final Logger LOG = Logger.getLogger(OdValuesService.class.getName());
@Autowired
private OdValuesDAO odValuesDAO;
/**
* Read data from table.
* @param odValuesEntity
* @return
*/
@Transactional (readOnly = true, value = "txtxManagerR")
public List<OdValuesEntity> getShare (OdValuesEntity odValuesEntity) {
odValuesDAO.getShare(odValuesEntity);
return odValuesDAO.getShare(odValuesEntity);
}
/** Add record to the table
*/
@Transactional (value = "txtxManagerR") /*I have two transaction managers for two different DataSources/
public void addOdValue (OdValuesEntity odValuesEntity) {
odValuesDAO.addOdValue(odValuesEntity);
}
}
我有一个调用这两种方法的测试。我可以使用getShare
方法从表中读取数据。但是在调用方法addOdValue
之后没有保存数据。这是我的问题。
当我在addOdValue
中取消注释与交易相关的代码时,一切正常。据我所知,在这种情况下,Spring事务管理器不起作用。
如何使用Spring @Transactional注释更正addOdValue
方法,或者可能是spring配置文件以保存数据库中的数据(打开和提交事务)?
我的Spring配置(上下文)包含与DB一起使用的下一个bean:
@Configuration
@EnableBatchProcessing
@EnableTransactionManagement
@ComponentScan
public class AppConfig {
@Bean
public BasicDataSource specRDataSource() {
BasicDataSource specRDataSource = new BasicDataSource();
specRDataSource.setDriverClassName("org.firebirdsql.jdbc.FBDriver");
specRDataSource.setUrl(specRDbUrl);
specRDataSource.setUsername(specRDbUser);
specRDataSource.setPassword(specRDbPassword);
specRDataSource.setMaxIdle(30);
specRDataSource.setMaxWaitMillis(10000);
specRDataSource.setValidationQuery("select 1 from rdb$database");
specRDataSource.setTestOnBorrow(false);
specRDataSource.setTestWhileIdle(true);
specRDataSource.setDefaultAutoCommit(true);
return specRDataSource;
}
@Bean
public BasicDataSource bortDataSource() {
BasicDataSource bortDataSource = new BasicDataSource();
bortDataSource.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
bortDataSource.setUrl(bortDbUrl);
bortDataSource.setUsername(bortDbUser);
bortDataSource.setPassword(bortDbPassword);
bortDataSource.setMaxIdle(2);
bortDataSource.setMaxWaitMillis(10000);
bortDataSource.setValidationQuery("select 1");
bortDataSource.setTestOnBorrow(true);
bortDataSource.setTestWhileIdle(true);
bortDataSource.setDefaultAutoCommit(true);
return bortDataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory (BasicDataSource bortDataSource) {
LocalContainerEntityManagerFactoryBean localConnectionFactoryBean = new LocalContainerEntityManagerFactoryBean();
localConnectionFactoryBean.setPersistenceXmlLocation("classpath:META-INF/persistence.xml");
localConnectionFactoryBean.setDataSource(bortDataSource);
localConnectionFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
return localConnectionFactoryBean;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactorySpec (BasicDataSource specRDataSource) {
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setPersistenceXmlLocation("classpath:META-INF/persistence.xml");
emf.setDataSource(specRDataSource);
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.dialect", "org.hibernate.dialect.FirebirdDialect");
emf.setJpaPropertyMap(properties);
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setGenerateDdl(true);
hibernateJpaVendorAdapter.setShowSql(true);
emf.setJpaVendorAdapter(hibernateJpaVendorAdapter);
return emf;
}
@Bean
public EntityManager emR (@Qualifier("entityManagerFactorySpec") EntityManagerFactory entityManagerFactorySpec) {
return entityManagerFactorySpec.createEntityManager();
}
@Bean
public EntityManager embort (@Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory ) {
return entityManagerFactory.createEntityManager();
}
@Bean
public JpaTransactionManager txtxManagerR (@Qualifier("entityManagerFactorySpec") EntityManagerFactory entityManagerFactorySpec) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactorySpec);
return txManager;
}
@Bean
public JpaTransactionManager txManagerbort (@Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory);
return txManager;
}
}
我的persistence.xml看起来像(如果需要):
<persistence-unit name="PersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.acap.app.JpaEntities.OdDocsEntity</class>
<class>com.acap.app.JpaEntities.OdValuesEntity</class>
.......
<class>com.acap.app.JpaEntities.OdOSharesEntity</class>
<properties>
<property name="hibernate.connection.url"
value="connection string"/>
<property name="hibernate.connection.driver_class" value="org.firebirdsql.jdbc.FBDriver"/>
<property name="hibernate.connection.username"/>
<property name="hibernate.connection.password"/>
<property name = "hibernate.show_sql" value = "false" />
<property name = "hibernate.format_sql" value = "false" />
</properties>
</persistence-unit>
堆栈跟踪未显示任何错误。谢谢你的帮助。
更新 测试运行:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class, loader = AnnotationConfigContextLoader.class)
public class OdValuesServiceTest {
static final Logger LOG = Logger.getLogger(OdValuesServiceTest.class.getName());
@Autowired
OdValuesService odValuesService;
@Autowired
DBCommonsService dbCommonsService;
@Commit
@Test
public void addOdValue() throws Exception {
OdValuesEntity odValuesEntity = new OdValuesEntity();
odValuesEntity.setId(dbCommonsService.getNextDocOD("OD_VALUES_ID_GEN"));
odValuesEntity.setSysname("Name" + DataGenerator.getRandomISIN());
odValuesEntity.setName("Name");
odValuesEntity.setIsIn((short) 1);
odValuesEntity.setvType(2);
odValuesEntity.setMfu((short) 0);
odValuesEntity.setIsin("AU000A0JP922");
odValuesEntity.setCfi("");
odValuesService.addOdValue(odValuesEntity);
}
}
答案 0 :(得分:1)
15.2.3交易管理
[..]默认情况下,框架将创建并回滚事务 每次测试 。[..]
所以,如果你的问题&#34;是,在使用@Transactional
时,测试中没有数据写入数据库,那么根本没有问题,它是弹簧默认工作的方式。如果那不是你想要的......
如果您想要提交事务 - 不寻常,但偶尔会有用 当你想要一个特定的测试来填充或修改 数据库 - 可以指示TestContext框架导致 提交事务而不是通过@Commit注释回滚。