Preamble - using Spring
I am confused as to the purpose of the spring @Transactional annotation. I thought from a few blog posts I've read that it would allow me to simplify transaction management and just write this, and it would handle connection/commit/rollback automagically:
public class DaoImpl implements Dao {
@Autowired
private SessionFactory sessionFactory;
@Transactional
public void saveOrUpdateOne(final AdditionalDataItem item) {
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(p_item);
}
}
However this gives me an exception: " Calling method 'saveOrUpdate' is not valid without an active transaction"
If I instead change the save method to this, it all works - so my question is, what is @Transactional doing?
@Override
@Transactional
public void saveOrUpdateOne(final AdditionalDataItem p_item) {
Session session = null;
Transaction trans = null;
try {
session = sessionFactory.getCurrentSession();
trans = session.beginTransaction();
TransactionStatus status = trans.getStatus();
session.saveOrUpdate(p_item);
trans.commit();
} catch (Exception e) {
LOGGER.error("Exception saving data: {}", e.getMessage());
if (trans != null) {
try {
trans.rollback();
} catch (RuntimeException rbe) {
LOGGER.error("Couldn’t roll back transaction", rbe);
}
}
} finally {
if (session != null && session.isOpen()) {
try {
session.close();
} catch (HibernateException ne) {
LOGGER.error("Couldn’t close session", ne);
}
}
}
}
For reference, I'm using Java 11 with Spring Framework 5.3.7 and hibernate 5.5.7 and have appropriate dao, session factory and tx manager beans:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="${sessionFactory.datasource}" />
<property name="configLocation" value="${sessionFactory.configLocation}" />
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="Dao" class="com.xxxxx.dao.DaoImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>