java Hibernate 4 - 调用 DAO 并初始化 sessionFactory bean

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13576777/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 13:17:00  来源:igfitidea点击:

Hibernate 4 - Calling DAO and Initializing sessionFactory bean

javaspringhibernate

提问by user1795832

I'm in the middle of updating my old program to Spring 3.2 and Hibernate 4 and am running into a couple of difficulties with sessionFactory (I was using hibernateTemplate before).

我正在将我的旧程序更新到 Spring 3.2 和 Hibernate 4,并且遇到了 sessionFactory 的一些困难(我之前使用过 hibernateTemplate)。

  1. I don't think the way I am accessing the DAO is the best way to do it, but I don't see how else to make it work. If I do a simple creation of the DAO object (CSSDAO d = new CSSDAOImpl();), the sessionFactory is always null. If I have it the way I do below, it works. What is the proper way to call the DAO methods? (please ignore the MVC portion of the controller, I know that needs its own work)

  2. I'm opening a new session in every method in the DAO. I know this isn't correct, as I should be getting the current session. But everytime I try to get the current session, it says one doesn't exist. How does the session get "initialized" the first time? I thought it would inject it based on the XML configuration, but that doesn't seem to be doing anything here. Any thoughts?

  1. 我不认为我访问 DAO 的方式是最好的方式,但我不知道还有什么方法可以让它工作。如果我简单地创建 DAO 对象 (CSSDAO d = new CSSDAOImpl();),则 sessionFactory 始终为 null。如果我按照下面的方式使用它,它就可以工作。调用 DAO 方法的正确方法是什么?(请忽略控制器的 MVC 部分,我知道这需要自己的工作)

  2. 我将在 DAO 中的每种方法中打开一个新会话。我知道这不正确,因为我应该获得当前会话。但是每次我尝试获取当前会话时,它都会说一个不存在。会话如何第一次“初始化”?我认为它会根据 XML 配置注入它,但这在这里似乎没有任何作用。有什么想法吗?

hibernate-cfg.xml

休眠-cfg.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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

    <bean id="myDataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver"></property>
        <property name="url" value="jdbc:derby:C:\Users\Steven\MyDB"></property>
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="packagesToScan" value="net.form" />
        <property name="dataSource" ref="myDataSource"></property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.DerbyTenSevenDialect
                </prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
        <property name="annotatedClasses">
            <list>
                <value>net.form.StyleChooser</value>
            </list>
        </property>
    </bean>

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager" />

    <bean id="CSSDAO" class="dao.CSSDAOImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

</beans>

DAO:

道:

package dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import net.form.StyleChooser;

public class CSSDAOImpl implements CSSDAO {

    private SessionFactory sessionFactory;

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Transactional
    public List selectAllCSS() {
        Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
        List l = session.createCriteria(StyleChooser.class).list();
        session.flush();
        tx.commit();
        return l;
    }

    @Transactional
    public StyleChooser selectCSSById(Integer ID) {
        Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
        StyleChooser sc = (StyleChooser) session.get(StyleChooser.class, ID);
        session.flush();
        tx.commit();        
        return sc;
    }

    @Transactional
    public Integer insertCSS(StyleChooser insertCSS) {
        Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
        Integer id = (Integer) session.save(insertCSS);
        session.flush();
        tx.commit();
        return id;
    }

    @Transactional
    public void deleteCSS(Integer CSSId) {
        Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
        StyleChooser sc = (StyleChooser) session.get(StyleChooser.class, CSSId);
        session.delete(sc);
        session.flush();
        tx.commit();
    }

    @Transactional
    public void updateCSS(StyleChooser cssWithNewValues) {
        Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
        session.update(cssWithNewValues);
        session.flush();
        tx.commit();        
    }
}

Accessing DAO...

访问 DAO...

package net.controllers;

import java.util.List;
import javax.servlet.http.HttpServletRequest;
import net.form.StyleChooser;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import dao.CSSDAOImpl;

@Controller
@RequestMapping("/stylechoosertable.html")
public class IndexController extends MultiActionController {

    Resource resource = new FileSystemResource(
            "C:/Users/Steven/Desktop/Programming/workspace/CSSGeneratorHibernate4/WebContent/WEB-INF/hibernate.cfg.xml");
    BeanFactory beanFactory = new XmlBeanFactory(resource);
    CSSDAOImpl dao = (CSSDAOImpl) beanFactory.getBean("CSSDAO");

    @RequestMapping(method = RequestMethod.GET)
    public ModelAndView showIndex(HttpServletRequest request) throws Exception {
        List<StyleChooser> styleChooser = dao.selectAllCSS();
        return new ModelAndView("stylechoosertable", "styleChooser", styleChooser);
    }
}

回答by Yogendra Singh

Few observation:

很少观察:

  1. In your retrieve methods, transaction shouldn't be used i.e. they should be non-transactional.

  2. Add <tx:annotation-driven transaction-manager="transactionManager"/>in your configuration to recognize the transactional annotations.

  3. If you use @Transactionalannotation then don't need to use programmatic transactions. Add the propagation attribute in the @Transactionalannotation as @Transactional(propagation=Propagation.REQUIRED)and leave the transaction management to Hibernate.

  4. For first time you need to open the session and if not closed you may use the same session next time. For getting the session, better to use an utility method as below:

    private Session getSession(SessionFactory sessionFactory){
     Session session = null;
     try{
         session = sessionFactory.getCurrentSession();
     }catch(HibernateException hex){
         hex.printStackTrace();
     }
     if(session == null && !session.isClosed()){
         session = sessionFactory.openSession();
     }
    }
    
  1. 在您的检索方法中,不应使用事务,即它们应该是非事务性的。

  2. 添加<tx:annotation-driven transaction-manager="transactionManager"/>您的配置以识别事务注释。

  3. 如果您使用@Transactional注释,则不需要使用程序化事务。在@Transactional注解中添加传播属性as@Transactional(propagation=Propagation.REQUIRED)并将事务管理留给 Hibernate。

  4. 第一次您需要打开会话,如果没有关闭,您下次可以使用同一个会话。为了获得session,最好使用如下的实用方法:

    private Session getSession(SessionFactory sessionFactory){
     Session session = null;
     try{
         session = sessionFactory.getCurrentSession();
     }catch(HibernateException hex){
         hex.printStackTrace();
     }
     if(session == null && !session.isClosed()){
         session = sessionFactory.openSession();
     }
    }
    

This way, you will get the session if available and open otherwise open a new session.

这样,您将获得会话(如果可用)并打开,否则打开一个新会话。