我在我的应用程序中使用spring和hibernate并使用spring transaction。
所以我在方法和带有数据库查询方法的DAO层上有注释@transaction的服务层。
@Transactional(readOnly = false)
public void get(){
}
问题是当我想在数据库中保存对象时,我必须在DAO层方法结束时使用session.flush()
。为什么?
我认为如果我注释了@ transaction,那么spring应该在完成服务方法时自动提交事务。
DAO层:
public BaseEntity saveEntity(BaseEntity entity) throws Exception {
try {
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(entity);
session.flush();
} catch (HibernateException he) {
throw new Exception("Failed to save entity " + entity);
}
return entity;
}
服务层:
@Transactional(readOnly = false)
public BaseEntity saveEntity(BaseEntity entity) throws Exception {
return dao.saveEntity(entity);
}
spring config:
<context:property-placeholder properties-ref="deployProperties" />
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Activate Spring Data JPA repository support -->
<jpa:repositories base-package="com" />
<!-- Declare a datasource that has pooling capabilities-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"
p:driverClass="${app.jdbc.driverClassName}"
p:jdbcUrl="${app.jdbc.url}"
p:user="${app.jdbc.username}"
p:password="${app.jdbc.password}"
p:acquireIncrement="5"
p:idleConnectionTestPeriod="60"
p:maxPoolSize="100"
p:maxStatements="50"
p:minPoolSize="10" />
<!-- Declare a JPA entityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:persistenceXmlLocation="classpath*:META-INF/persistence.xml"
p:persistenceUnitName="hibernatePersistenceUnit"
p:dataSource-ref="dataSource"
p:jpaVendorAdapter-ref="hibernateVendor"/>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource" p:configLocation="${hibernate.config}"
p:packagesToScan="com" />
<!-- Specify our ORM vendor -->
<bean id="hibernateVendor" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:showSql="false"/>
<!-- Declare a transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory"/>
答案 0 :(得分:3)
是的,如果你的DAO方法有@Transactional
,那么你不需要手动刷新会话,如果方法中的操作成功,hibernate将负责刷新会话作为提交事务的一部分。< / p>
点击此链接,了解@Transactional的工作原理 - Spring - @Transactional - What happens in background?
答案 1 :(得分:0)
默认情况下,hibernate会堆叠其查询,以便在最终执行到数据库时对其进行优化。
刷新的漏洞是刷新此堆栈并在事务中将其执行到数据库中。你离开jvm的“保存”房子并在一个大的奇怪的数据库上执行你的查询。
这就是为什么你不能在没有同花顺的情况下选择刚刚保存的东西。它根本就不在数据库中。
提交的含义是在事务结束后结束,并使数据库的更改对其他人可见。一旦执行了提交,就不再有可能返回。
坦率地说,我不确定它是否是最佳实践,但对于正常的CRUD操作,您应该能够将flush添加到您的dao层中。 这样您就不必担心它会进入服务层。
如果您希望java优化您的交易,那么您必须将其添加到您的服务层。但请记住,在没有任何问题时你不需要解决性能问题!将所有代码刷新到服务层不利于代码可读性。保持简单和愚蠢;)