2015-06-23 23 views
0

我想从DAO类中删除begin和commit事务,并且我需要使用Transactional注释。应该怎么做?现在 ,例外的是org.hibernate.HibernateException:的createQuery无效无活动事务Java和Spring。事务性注释@Transactional

CoursesDAO.java

public interface CoursesDAO { 

public Course createCourse(Course course); 

public Course findCourseById(Integer key); 

public Course updateCourse(Course course); 

public void deleteCourse(Course course); 

public List<Course> getAllCourses(); 

public List<Course> getAllCoursesByCategory(String category); 

public List<Course> getAllCoursesWhichNoProposal(); 

} 

CoursesDAOImpl.java

@Repository 
public class CoursesDAOImpl implements CoursesDAO { 

@Autowired 
private SessionFactory sessionFactory; 

public Course createCourse(Course course) { 

    Session session = sessionFactory.getCurrentSession(); 
    //session.beginTransaction(); 
    Integer id = (Integer) sessionFactory.getCurrentSession().save(course); 
    course.setId(id); 
    //session.getTransaction().commit(); 

    return course; 
}; 

public Course findCourseById(Integer id) { 

    Session session = sessionFactory.getCurrentSession(); 
    //session.beginTransaction(); 
    Course course = (Course) session.get(Course.class, id); 
    //session.getTransaction().commit(); 

    return course; 
} 


public Course updateCourse(Course course) { 

    Session session = sessionFactory.getCurrentSession(); 
    //session.beginTransaction(); 
    session.merge(course); 
    //session.getTransaction().commit(); 

    return course; 
}; 

public void deleteCourse(Course course) { 

    Session session = sessionFactory.getCurrentSession(); 
    //session.beginTransaction(); 
    session.delete(course); 
    //session.getTransaction().commit();  



}; 

public List<Course> getAllCourses() { 

    Session session = sessionFactory.getCurrentSession(); 
    //session.beginTransaction(); 
    List listCourses = session.createQuery("from Course").list(); 
    //session.getTransaction().commit(); 
    return listCourses; 
} 



public List<Course> getAllCoursesByCategory(String category) { 

    Session session = sessionFactory.getCurrentSession(); 
    //session.beginTransaction(); 
    List listCoursesByCategory = session.createQuery("from Course c where c.category='"+category+"'").list(); 
    //session.getTransaction().commit(); 

    return listCoursesByCategory; 
} 


public List<Course> getAllCoursesWhichNoProposal() { 

    Session session = sessionFactory.getCurrentSession(); 
    //session.beginTransaction(); 
    List listCoursesNoProposal = session.createQuery("from Course c where c.state not like 'Proposal' and c.state not like 'Rejected'").list(); 
    //session.getTransaction().commit(); 

    return listCoursesNoProposal; 
} 

} 

CourseService.java

public interface CourseService { 

public Course findCourseById(Integer id); 

public Course updateCourse(Course course); 

public Course createCourse(Course course); 

public void deleteCourse(Course course); 

public List<Course> getAllCourses(); 

public List<Course> getAllCoursesByCategory(String category); 

public List<Course> getAllCoursesWhichNoProposal(); 

} 

CourseServiceImpl.java

@Service 
public class CourseServiceImpl implements CourseService { 
@Autowired 
private CoursesDAO coursesDAOImpl; 


@Transactional 
public Course findCourseById(Integer id) { 

    Course course = coursesDAOImpl.findCourseById(id); 

    return course; 
} 
@Transactional 
public Course updateCourse(Course course) { 

    // Course.openCurrentSessionwithTransaction(); 

    course = coursesDAOImpl.updateCourse(course); 

    // Course.closeCurrentSessionwithTransaction(); 
    return course; 
} 
@Transactional 
public Course createCourse(Course course) { 

     //Course.openCurrentSessionwithTransaction(); 

    course = coursesDAOImpl.createCourse(course); 

     //Course.closeCurrentSessionwithTransaction(); 
    return course; 
} 
@Transactional 
public List<Course> getAllCourses() { 

    // Course.openCurrentSessionwithTransaction(); 

    List<Course> listCourses = coursesDAOImpl.getAllCourses(); 

    // Course.closeCurrentSessionwithTransaction(); 
    return listCourses; 
} 
@Transactional 
public List<Course> getAllCoursesByCategory(String category) { 

    // Course.openCurrentSessionwithTransaction(); 

    List<Course> listCoursesByCategory = coursesDAOImpl 
      .getAllCoursesByCategory(category); 

    // Course.closeCurrentSessionwithTransaction(); 
    return listCoursesByCategory; 
} 

@Transactional 
public List<Course> getAllCoursesWhichNoProposal() { 

    // Course.openCurrentSessionwithTransaction(); 

    List<Course> listCoursesNoProposal = coursesDAOImpl 
      .getAllCoursesWhichNoProposal(); 

    // Course.closeCurrentSessionwithTransaction(); 
    return listCoursesNoProposal; 
} 
@Transactional 
public void deleteCourse(Course course) { 
    coursesDAOImpl.deleteCourse(course); 

}; 

应用contex.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 
xmlns:security="http://www.springframework.org/schema/security" 
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd 
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"> 

<mvc:annotation-driven /> 

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
    destroy-method="close" 
    p:driverClassName="org.h2.Driver" 
    p:url="jdbc:h2:tcp://localhost:9092/~/QWE;INIT=create schema if not exists QWE\;" 
    p:username="sa" 
    p:password="" /> 

<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="hibernateProperties"> 
    <props> 
<prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop> 
<prop key="hibernate.show_sql">true</prop> 
<prop key="connection.pool_size">1</prop> 
<prop key="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</prop> 
<prop key="hibernate.current_session_context_class">thread</prop> 
<prop key="hibernate.hbm2ddl.auto">update</prop> 
<prop key="hibernate.default_schema">QWE</prop> 
</props>  
</property> 

<property name="annotatedClasses"> 
    <list> 
    <value>com.epam.edu.jtc.entity.User</value> 
    <value>com.epam.edu.jtc.entity.Category</value> 
    <value>com.epam.edu.jtc.entity.Course</value> 
    <value>com.epam.edu.jtc.entity.UserCourse</value> 
    <value>com.epam.edu.jtc.entity.ManagerCourse</value> 
    </list> 
</property> 
</bean>   

<!-- FreeMarker Configuration --> 
<bean id="freemarkerEmailConfig" class="freemarker.template.Configuration"> 
<property name="directoryForTemplateLoading" value="WEB-INF/pages/templates" /> 
<property name="objectWrapper"> 
    <bean class="freemarker.template.DefaultObjectWrapper"/> 
</property> 

</bean> 

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
<property name="sessionFactory" ref="sessionFactory" /> 
</bean> 
<tx:annotation-driven transaction-manager="transactionManager"/> 
<context:component-scan base-package="com.epam.edu.jtc" /> 

</beans> 
+0

你可以发布你的spring-hibernate配置 – AntJavaDev

+0

我显示了application-context.xml – Dmitry88

+0

为什么你注释掉了?春天应该如何收集你的注释类/方法? – AntJavaDev

回答

1

我想在这里你有概念的问题。

适当的架构应该是有一个调用存储库的事务服务。像这样的东西。

@Service 
public class CoursesServiceImpl implements CoursesService { 

    @Autowired 
    private CoursesDAO coursesDAO; 

    @Override 
    @Transactional 
    public void insertCourses(Course courses) { 
    coursesDAO.createCourse(courses); 
    } 

}

然后你的资料库

@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

加1用于在服务级别注释 –

+0

我不理解它(“在服务级别注释加1”) – Dmitry88

0

设置正确的事务管理器后,只是试图@Transactional注释移动到方法的实现类

@Repository 
    public class CoursesDAOImpl implements CoursesDAO { 

    @Autowired 
    private SessionFactory sessionFactory; 

    @Transactional 
public Course createCourse(Course course) { 
0

你的配置有两个缺陷。

首先在使用@Transactional时,还必须在应用程序上下文文件中包含一个<tx:annotation-driven />标签,以使其清晰明了。如果不是,你的@Transactional将不会做任何事情。

简单添加<tx:annotation-driven transaction-manager="txManager/>,因为您将其命名为不同于transactionManager(默认名称)。当然,您还必须将正确的xsd添加到头部以使tx命名空间可用。

xmlns:tx="http://www.springframework.org/schema/tx" 

并将其添加到您的schemaLocation属性中。

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 

其次,您已在您的休眠配置中配置了hibernate.current_session_context_class属性。这打破了适当的集成与春天,它将其设置为一个自定义的春季班,但您的设置覆盖此。删除此属性。

要考虑的另一件事是实际的事务边界应该是您的服务层而不是您的数据访问层。您的服务方法是全或无操作,如果您有3个数据库调用,则它们都应该参与相同的事务。使用您的设置,您将获得3个单独的事务,例如在执行多个更新时可能会使数据库处于不受欢迎的状态。我建议将@Transactional移到您的服务层而不是数据访问层。