Reputation: 6650
I am quite confused with Spring and Hibernate transactions. I have the following sample code.
I am wondering if
getCurrentSession().beginTransaction()
as well, should I use it in conjunction with @Transactional
at all?Configuration
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:2000/HiberProject" />
<property name="username" value="jack" />
<property name="password" value="jack" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
depends-on="dataSource">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.hiberproject.model" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
Service
@Service
public class SampleRecordsServiceImpl implements SampleRecordsService{
@Autowired
SampleRecordsRepository sampleRecordsRepository;
@Override
@Transactional(readOnly=true)
public Record retrieveRecord(long id){
return sampleRecordsRepository.retrieveRecord(id);
}
}
Repository
@Repository
public class SampleRecordsRepository implements SampleRecordsRepository{
@Autowired
SessionFactory sessioFactory;
@Override
public Record retrieveRecord(long id){
return (Record) sessionFactory.getCurrentSession().get(Record.class,id);
}
}
Upvotes: 7
Views: 3060
Reputation: 11926
The @Transactional
annotation itself defines the scope of a single database transaction. The database transaction happens inside the scope of a persistence context.
The persistence context is just a synchronizer object that tracks the state of a limited set of Java objects and makes sure that changes on those objects are eventually persisted back into the database.
For @Transactional
annotation you can set propagation attribute, using Propagation you can handle your tarnsaction in different way like Propagation.REQUIRES_NEW
(if you need new transaction on every request) . the default propagation is REQUIRED
.
session.beginTransaction()
will also either begin a new Transaction if one isn't present, or it will use an existing transaction to begin the unit of work specified.
So you should use either one of approach to manage the transaction.
Upvotes: 4
Reputation: 7126
Yes that's Okay to use only @Transactional
annotation like this when you use Spring to manage your transaction.
No. You don't need to do that! If you use @Transactional
annotation in your service, then Spring takes care of your persistence layer to manage transaction. All you need is to declare persistence layer specific transaction manager in your Spring configuration. So you do not need to manage transaction with hibernate sessions by using session.beginTransaction()
together with @Transactional
.
For more information please see the documentation of using @Transactional
.
Upvotes: 2