Hibernate session.flush with spring @transactional

I use Spring and Hibernate in my application and use Spring Transaction.

So, I have a service layer with @Transaction annotation for methods, and the DAO layer has methods for querying the database.

 @Transactional(readOnly = false) public void get(){ } 

The problem is that when I want to store the object in the database, I have to use session.flush() at the end of the DAO level method. Why?

I think that if I annotated @Transaction , then Spring should automatically commit the transaction after the service method completes.

DAO Level:

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

Service Level:

  @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"/> 
+11
source share
2 answers

Yes, if you have @Transactional for your DAO method, you do not need to manually clear the session, hibernate will take care to clear the session as part of the transaction if the operations in this method are successful.

Check out this link to learn how @Transactional - Spring - @Transactional - What happens in the background?

+5
source

By default, hibernation puts its requests, so they can be optimized when they are finally executed in the database.

The flash hole point is to clear this stack and execute it in a transaction in the database. You leave the "save" jvm house and execute your request in a large weird database.

This is why you cannot choose what you just saved without a flash. It is simply not in the database.

The commit value ends after the transaction and makes the database changes visible to others. After the fixation is completed, return is not possible.

Frankly, I'm not quite sure if this is the best practice, but for regular CRUD operations you can add flush to your dao level. Thus, you do not need to worry about this at the service level.

If you want java to optimize your transaction, you will have to add it to your service level. But remember that you do not need to solve performance problems when they are not! Dropping all code to the service level is not suitable for reading code. Keep it simple and stupid;)

0
source

Source: https://habr.com/ru/post/1203714/


All Articles