Java and Spring. Transactional annotation @Transactional

后端 未结 3 882
不知归路
不知归路 2021-01-29 03:39

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

相关标签:
3条回答
  • 2021-01-29 04:00

    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.

    0 讨论(0)
  • 2021-01-29 04:03

    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;
    };
    
    0 讨论(0)
  • 2021-01-29 04:05

    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) {
    
    0 讨论(0)
提交回复
热议问题