2015-06-23 79 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移到您的服務層而不是數據訪問層。

相關問題