I want to Remove begin and commit transactions from DAO class , and I need to use Transactional annotation. How it should be done? Now , exception is org.hibernate.HibernateE
There are 2 flaws in your configuration.
First when using @Transactional
you also have to make this clear to your configuration by including a <tx:annotation-driven />
tag in your application context file. If not your @Transactional
is going to do nothing.
Simple add <tx:annotation-driven transaction-manager="txManager/>
, as you named it different then transactionManager
(the default name). Of course you would also have to add the correct xsd to the header to make the tx
namespace available.
xmlns:tx="http://www.springframework.org/schema/tx"
and add this to your schemaLocation
attribute.
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
Second you have configured the hibernate.current_session_context_class
property in your hibernate configuration. This breaks proper integration with spring which sets it to a custom Spring class, however your setting overrides this. Remove this property.
Another thing to consider is that the actual transactional boundary should be your service layer and not your data access layer. Your service method is an all or nothing operation, if you have 3 database calls they should all participate in the same transaction. With your setup you will get 3 individual transactions, which can leave your database in an undesired state when doing multiple updates for instance. I suggest to move the @Transactional
to your service layer instead of the data access layer.
I think here you have a problem of concept.
The proper architecture would be to have a transactional service that invoke a repository. Something like this.
@Service
public class CoursesServiceImpl implements CoursesService {
@Autowired
private CoursesDAO coursesDAO;
@Override
@Transactional
public void insertCourses(Course courses) {
coursesDAO.createCourse(courses);
}
}
Then your repository
@Repository
public class CoursesDAOImpl implements CoursesDAO {
@Autowired
private SessionFactory sessionFactory;
public Course createCourse(Course course) {
Session session = sessionFactory.getCurrentSession();
//session.beginTransaction();
Integer id = (Integer) session.save(course);
course.setId(id);
//session.getTransaction().commit();
return course;
};
After setting a correct transaction manager, just tried to move the @Transactional annotation to the method on the implemented class
@Repository
public class CoursesDAOImpl implements CoursesDAO {
@Autowired
private SessionFactory sessionFactory;
@Transactional
public Course createCourse(Course course) {