Hibernate/Spring3:无法初始化代理-没有会话
我是Spring的新手,所以我将Spring 3.0M3放在Mac上的Tomcat服务器上,创建了一个Eclipse项目,完成了Hello World,然后希望使对象与Hibernate保持一致.我已经在MySQL服务器上创建了一个User表,并创建了一个包含所有getter和setter的User对象(我真的希望Java从这里的Objective-C队列中添加动态属性.生成的属性代码太多了,代码杂乱无章) ,制作了一个UserDao对象来查找和保存用户,并进行了Bean配置.进行得很好...除了未初始化会话外.为什么是这样?我可以使用这些凭据从这台计算机访问数据库.
I'm new at Spring, so I put Spring 3.0M3 on a Tomcat server on my Mac, made an Eclipse project, completed a Hello World and then wanted to make an object persist with Hibernate. I've made a User table on my MySQL server, made a User object with all getters and setters (I really wish Java would take a queue from Objective-C here and add dynamic properties. Too much code clutter with generated property-code), made a UserDao object to look up and save a User, and made the bean config. It goes fairly well... except for that the session isn't initialized. Why is this? I can access the database just fine from this computer using those credentials.
我意识到这可能只是普通的初学者,但是我在谷歌搜索时发现的所有错误都是在从Hibernate 2过渡到3时中途丢失会话的人.据我所知,会话从未进行过.
I realize that this is probably just normal beginner stuff, but all I've found on the error while googling has been people that are loosing the sessions mid-way when transitioning from Hibernate 2 to 3. I'm not transitioning, and as far as I can tell the session is never made.
这是我的错误:
SEVERE: Servlet.service() for servlet HelloApp threw exception
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
at com.saers.data.entities.User$$EnhancerByCGLIB$$c2f16afd.getName(<generated>)
at com.saers.view.web.controller.HelloWorldController.handleRequestInternal(HelloWorldController.java:22)
at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:763)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:709)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:613)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:525)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:637)
这是我为相关bean设置的servlet:
Here is my servlet config for the related beans:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://10.0.0.3:3306/HelloDB" />
<property name="username" value="hello" />
<property name="password" value="w0rld" />
<property name="initialSize" value="2" />
<property name="maxActive" value="5" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="annotatedClasses">
<list>
<value>com.saers.data.entities.User</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.lazy">false</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="userDAO" class="com.saers.data.dao.UserDao">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="txProxyTemplate" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</bean>
<bean id="userService" parent="txProxyTemplate">
<property name="target">
<bean class="com.saers.business.UserServiceImpl">
<property name="userDao" ref="userDAO"/>
</bean>
</property>
<property name="proxyInterfaces" value="com.saers.business.UserService"/>
</bean>
<bean name="/" class="com.saers.view.web.controller.HelloWorldController">
<property name="userService" ref="userService"/>
</bean>
这是我的用户类别:
package com.saers.data.entities;
import java.util.Date;
import java.io.Serializable;
import javax.persistence.*;
@Entity
@Table(name = "User")
public class User implements Serializable {
private static final long serialVersionUID = -6123654414341191669L;
@Id
@Column(name = "WebUserId")
private String WebUserId;
@Column(name = "Name")
private String Name;
/**
* @return the webUserId
*/
public synchronized String getWebUserId() {
return WebUserId;
}
/**
* @param webUserId the webUserId to set
*/
public synchronized void setWebUserId(String webUserId) {
WebUserId = webUserId;
}
/**
* @return the name
*/
public synchronized String getName() {
return Name;
}
/**
* @param name the name to set
*/
public synchronized void setName(String name) {
Name = name;
}
}
这是我的UserDao:
And here is my UserDao:
package com.saers.data.dao;
import java.util.List;
import com.saers.data.entities.User;
import org.springframework.orm.hibernate3.support.*;
public class UserDao extends HibernateDaoSupport {
public void saveUser(User user) {
getHibernateTemplate().saveOrUpdate(user);
}
public User lookupUser(String WebUserId) {
User user = getHibernateTemplate().load(User.class, WebUserId);
return user;
return user;
}
}
这是我的UserService界面
Here's my UserService interface
public interface UserService {
public User lookupUser(String webUserId);
public void setUserDao(UserDao userDao);
}
及其实现:
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public User lookupUser(String webUserId) {
return userDao.lookupUser(webUserId);
}
}
最后,这是我的HelloWorldController:
And finally, here's my HelloWorldController:
package com.saers.view.web.controller;
import com.saers.data.entities.User;
import com.saers.business.UserService;
import org.springframework.web.servlet.mvc.*;
import org.springframework.web.servlet.*;
import javax.servlet.http.*;
import org.apache.commons.logging.*;
public class HelloWorldController extends AbstractController {
protected final Log logger = LogFactory.getLog(getClass());
@Override
public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
logger.info("Get bean");
User user = userService.lookupUser("helloUser");
logger.info("Found out that this user was last changed " + user.getName());
logger.info("Return View");
ModelAndView mv = new ModelAndView("HelloWorld.jsp", "user", user);
return mv;
}
private UserService userService = null;
public void setUserService(UserService userService) {
this.userService = userService;
}
}
我希望您有一些我可以使用的好技巧:-)如果代码中还有其他问题,您会觉得我做错了/非有弹性的方法,那么我也很乐意听到.
I hope you have some good tips I can use :-) If there's anything else in the code you feel that I'm doing the wrong/non-spring way, I would love to hear about that as well.
欢呼
Nik
您的堆栈跟踪与您为UserDao
发布的示例代码不匹配.跟踪显示您正在从UserDao.lookupUser()
调用HibernateTemplate.initialize()
,但是示例代码没有执行任何操作(同样不应该,在这里不应调用initialize()
).
Your stack trace does not match up with the sample code you posted for UserDao
. The trace says that you're calling HibernateTemplate.initialize()
from UserDao.lookupUser()
, but your sample code is doing no such thing (as well it shouldn't, initialize()
should not be called here).
好的,对于新的堆栈跟踪,看来问题仅在于您正在调用hibernateTemplate.load()
,它仅应在特定情况下使用(这不是其中一种).您可能应该呼叫hibernateTemplate.get()
.
OK, with the new stack trace, it seems the problem is simply that you're calling hibernateTemplate.load()
, which should only be used in specific circumstances (and this isn't one of them). You should probably be calling hibernateTemplate.get()
.