Java Spring和hibernate:query.list()执行不超过两次
我有一个java类,还有两个类似于这里的方法Java Spring和hibernate:query.list()执行不超过两次,java,spring,hibernate,Java,Spring,Hibernate,我有一个java类,还有两个类似于这里的方法 public Object noOfEmployees() { List<Employee> emp = null; String u = user.getUserName(); if ("user1".equals(u)) { Query query = getHibernateTemplate().getSessionFactory().openSessi
public Object noOfEmployees() {
List<Employee> emp = null;
String u = user.getUserName();
if ("user1".equals(u)) {
Query query = getHibernateTemplate().getSessionFactory().openSession()
.createSQLQuery("select * from employee where job='System Analyst'")
.addEntity(EMPLOYEE.class);
emp = query.list();
getHibernateTemplate().getSessionFactory().openSession().close();
} else if ("user2".equals(u)) {
Query query = getHibernateTemplate().getSessionFactory().openSession()
.createSQLQuery("select * from employee where job='DBA'")
.addEntity(EMPLOYEE.class);
emp = query.list();
getHibernateTemplate().getSessionFactory().openSession().close();
}
return emp.size();
}
public对象noOfEmployees(){
列表emp=null;
字符串u=user.getUserName();
如果(“用户1”。等于(u)){
Query Query=getHibernateTemplate().getSessionFactory().openSession()
.createSQLQuery(“从job='System Analyst'所在的员工中选择*)
.附录(员工类别);
emp=query.list();
getHibernateTemplate().getSessionFactory().openSession().close();
}如果(“user2”。等于(u)){
Query Query=getHibernateTemplate().getSessionFactory().openSession()
.createSQLQuery(“从job='DBA'所在的员工中选择*)
.附录(员工类别);
emp=query.list();
getHibernateTemplate().getSessionFactory().openSession().close();
}
返回emp.size();
}
当我运行应用程序时,我是这样得到输出的:
谢谢大家! 显然,这个代码的问题
Query query = getHibernateTemplate().getSessionFactory().openSession().
...
getHibernateTemplate().getSessionFactory().openSession().close();
使用此getHibernateTemplate().getSessionFactory().openSession().close()
您将获得一个新会话并将其关闭
您应该使用HQL
Query query = session.createQuery("from Employee where job='System Analyst'");
List<Employee> emp = query.list();
你的代码在很多方面都有缺陷。。。首先,您不应该使用
HibernateTemplate
,除非您使用的是非常旧的应用程序,否则请使用普通的SessionFactory
。有关更多信息,请参阅
第二,当使用Spring时,请使用Spring来管理您的资源,即在本例中是会话
,或者如果您想自己做,至少要正确地管理它
因此,简而言之,使用SessionFactory
并使用getCurrentSession
而不是openSession
。并使用适当的查询
@Autowired
private SessionFactory sf;
@Transactional
public Long noOfEmployees() {
final String query = "select count(*) from employee where job=:job";
Query q = sf.getCurrentSession().createSQLQuery(query);
if ("user1".equals(u)) {
q.setParameter("job", "System Analyst");
} else if ("user2".equals(u) ) {
q.setParameter("job", "DBA");
}
return (Long) query.uniqueResult();
}
@Transactional
将使spring管理资源,假设您的上下文中有
,并正确添加了HibernateTransactionManager
,我已尝试在一定程度上更改我在多个级别上有缺陷的代码。感谢@M.Deinum和@v.ladynev的迅速回复
下面给出的只是提到从HibernateTemplate移动到SessionFactory的更改的片段:
//IndexService
@Transactional
public class IndexService {
User user;
SessionFactory sf;
public IndexService(User user, SessionFactory sf) {
this.user = user;
this.sf = sf;
}
//This method is used to get the number of employees based on users.
public Object noOfEmployees() {
String u = user.getUserName();
final String query = "select count(*) from employee where job=:job";
Query q = sf.getCurrentSession().createSQLQuery(query);
if ("user1".equals(u)) {
q.setParameter("job", "System Analyst");
} else if ("user2".equals(u) ) {
q.setParameter("job", "DBA");
}
return q.uniqueResult();
}
--------------------------------------------------------------------------------------
//Index
@Controller
@Transactional
public class Index {
@Autowired
User user;
@Autowired
SessionFactory sf;
@RequestMapping("/index")
public ModelAndView getIndex() {
System.out.println("user.getUserName() In Index = " + user.getUserName());
ModelAndView modelAndView = new ModelAndView("index");
IndexService indexService = new IndexService(user, sf);
modelAndView.addObject("noOfEmployees", indexService.noOfEmployees());
return modelAndView;
}
}
--------------------------------------------------------------------------------------
//spring-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="basicDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url"
value="jdbc:mysql://localhost/database_name"></property>
<property name="username" value="user"></property>
<property name="password" value="password"></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="basicDataSource"></property>
<property name="mappingResources" value="myBeans.hbm.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
//索引服务
@交易的
公共类索引服务{
用户;
SessionFactory sf;
公共索引服务(用户、会话工厂sf){
this.user=用户;
this.sf=sf;
}
//此方法用于根据用户获取员工数量。
公共对象noOfEmployees(){
字符串u=user.getUserName();
final String query=“从员工中选择count(*),其中job=:job”;
Query q=sf.getCurrentSession().createSQLQuery(查询);
如果(“用户1”。等于(u)){
q、 设置参数(“工作”、“系统分析员”);
}否则,如果(“用户2”。等于(u)){
q、 setParameter(“作业”、“DBA”);
}
返回q.uniqueResult();
}
--------------------------------------------------------------------------------------
//索引
@控制器
@交易的
公共类索引{
@自动连线
用户;
@自动连线
SessionFactory sf;
@请求映射(“/index”)
公共模型和视图获取索引(){
System.out.println(“Index=“+user.getUserName()”)中的user.getUserName();
ModelAndView ModelAndView=新的ModelAndView(“索引”);
IndexService IndexService=新的IndexService(用户,sf);
添加对象(“noOfEmployees”,indexService.noOfEmployees());
返回模型和视图;
}
}
--------------------------------------------------------------------------------------
//spring-servlet.xml
org.hibernate.dialogue.mysql5dialogue
更新
真的
从HibernateTemplate更改为SessionFactory时遇到的问题:
1.SessionFactory的NullPointerException
在索引类中
@自动连线
SessionFactory sf
并将其作为论点通过
IndexService IndexService=新的IndexService(用户,sf)
2.没有绑定到线程的Hibernate会话,配置不允许在此创建非事务会话
我把@Transactional也放在索引上面。它是我应用程序中的控制器
再次感谢@M.Deinum和@v.ladynev!您能解释一下什么是
//IndexService
@Transactional
public class IndexService {
User user;
SessionFactory sf;
public IndexService(User user, SessionFactory sf) {
this.user = user;
this.sf = sf;
}
//This method is used to get the number of employees based on users.
public Object noOfEmployees() {
String u = user.getUserName();
final String query = "select count(*) from employee where job=:job";
Query q = sf.getCurrentSession().createSQLQuery(query);
if ("user1".equals(u)) {
q.setParameter("job", "System Analyst");
} else if ("user2".equals(u) ) {
q.setParameter("job", "DBA");
}
return q.uniqueResult();
}
--------------------------------------------------------------------------------------
//Index
@Controller
@Transactional
public class Index {
@Autowired
User user;
@Autowired
SessionFactory sf;
@RequestMapping("/index")
public ModelAndView getIndex() {
System.out.println("user.getUserName() In Index = " + user.getUserName());
ModelAndView modelAndView = new ModelAndView("index");
IndexService indexService = new IndexService(user, sf);
modelAndView.addObject("noOfEmployees", indexService.noOfEmployees());
return modelAndView;
}
}
--------------------------------------------------------------------------------------
//spring-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="basicDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url"
value="jdbc:mysql://localhost/database_name"></property>
<property name="username" value="user"></property>
<property name="password" value="password"></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="basicDataSource"></property>
<property name="mappingResources" value="myBeans.hbm.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>