我正在更新我的舊程序到Spring 3.2和Hibernate 4,並遇到與sessionFactory(我之前使用hibernateTemplate)的一些困難。休眠4 - 調用DAO和初始化sessionFactory bean
我不認爲我訪問DAO的方法是做它的最佳方式,但我不明白怎麼回事,使其工作。如果我做了一個簡單的DAO對象創建(CSSDAO d = new CSSDAOImpl();),sessionFactory始終爲空。如果我按照以下的方式使用它,它就可以工作。調用DAO方法的正確方法是什麼? (請忽略控制器的MVC部分,我知道需要自己的工作)
我在DAO中的每個方法中打開一個新的會話。我知道這是不正確的,因爲我應該得到當前會議。但每次我嘗試獲得當前會話時,都會說不存在。會話如何第一次「初始化」?我以爲它會根據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();
}
}
訪問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);
}
}
感謝您的回答。所以我需要從方法中刪除事務行,並通過Transactional註釋將事務留在休眠狀態,對嗎?爲什麼我必須開新會議?我認爲配置會通過注入創建sessionFactory和會話?情況並非如此嗎?最後,應如何準確訪問DAO(問題1) – user1795832
@ user1795832:1.正確。只要確保配置正確並且事務按預期工作即可。 2.您只創建會話工廠。您需要使用會話工廠獲取/創建會話。 3.請參閱https://community.jboss.org/wiki/GenericDataAccessObjects獲取DAO訪問模式。 –
好,太棒了。但是每次調用getSession時我都會遇到異常,所以在任何情況下,sessionFactory中的當前會話都不存在。這是爲什麼?會話一旦退出事務邊界就會被破壞嗎?另外,對於deleteCSS和updateCSS方法,我還必須調用flush()才能使查詢通過,但我不必爲insertCSS。那裏有任何想法? PS對不起,當我出於某種原因將它放在那裏時,我會一直刪除@YOUR USER NAME,所以不確定是否收到通知。 – user1795832