Hibernate/Spring3: impossible d'initialiser le proxy - pas de Session
Je suis nouveau au Printemps, j'ai donc mis le Printemps 3.0M3 sur un serveur Tomcat sur mon Mac, fait un projet Eclipse, a réalisé un Bonjour à tout le Monde et puis il a voulu faire un objet persistent avec la veille prolongée. J'ai fait un tableau d'Utilisateur sur mon serveur MySQL, fait un objet Utilisateur avec tous les getters et les setters (je souhaite vraiment que Java serait prendre une file d'attente d'Objective-C d'ici et d'ajouter des propriétés dynamiques. Trop de l'encombrement de code générés bien-code), a fait une UserDao objet à regarder et enregistrer un Utilisateur, et fait de la fève de config. Il va assez bien... sauf que la session n'est pas initialisé. Pourquoi est-ce? Je peux accéder à la base de l'amende juste à partir de cet ordinateur à l'aide de ces informations d'identification.
Je me rends compte que c'est juste normal débutant choses, mais tout ce que j'ai trouvé sur l'erreur alors que google a eu des gens qui perdent de l'séances à mi-chemin lors de la transition de mise en veille prolongée de 2 à 3. Je ne suis pas la transition, et aussi loin que je peux dire que la session n'est jamais fait.
Voici mon erreur:
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)
Voici ma servlet config pour les haricots:
<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>
Voici ma classe d'Utilisateur:
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;
}
}
Et voici mon 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;
}
}
Voici mon UserService interface
public interface UserService {
public User lookupUser(String webUserId);
public void setUserDao(UserDao userDao);
}
et sa mise en œuvre:
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);
}
}
Et enfin, voici mon 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;
}
}
J'espère que vous avez quelques bons conseils que je peux utiliser 🙂 Si il y a autre chose dans le code que tu sens que je suis en train de faire le mal/non-printemps façon, j'aimerais entendre à ce sujet ainsi.
Acclamations
Nik
OriginalL'auteur niklassaers | 2009-07-30
Vous devez vous connecter pour publier un commentaire.
Votre trace de la pile ne correspond pas à l'exemple de code que vous avez posté pour
UserDao
. La trace dit que vous appelezHibernateTemplate.initialize()
deUserDao.lookupUser()
, mais votre exemple de code est en fait rien (et il ne devrait pas,initialize()
ne doit pas être appelée ici).Edit: OK, avec la nouvelle trace de la pile, il semble que le problème est tout simplement que vous appelez
hibernateTemplate.load()
, qui ne devrait être utilisé que dans des circonstances spécifiques (et ce n'est pas l'un d'eux). Vous devriez probablement être l'appel dehibernateTemplate.get()
.Stacktrace mise à jour 🙂
Aha!!! Merci TRÈS beaucoup!!!! Le livre (tout à fait excellent, j'ai à ajouter), le Printemps à Actino sur la page 190 a dit .load() explicitement, de sorte que j'ai utilisé. Peut-être que cela a changé depuis le livre a été écrit. Ce n' .load() signifie maintenant/comment est-il différent de .get()? Maintenant, tout fonctionne super. Merci beaucoup 🙂
jag (il suffit de demander à google)
Je l'ai fait, hibernate.org n'était pas de répondre
OriginalL'auteur skaffman
Lorsque vous ne l'dao appel, la "charge" de l'objet. La charge n'atteint pas la base de données, il sera de retour un proxy sur l'objet de façon à ce que la base de données est seulement quand c'est absolument nécessaire.
Vous n'avez pas à démarrer une transaction avant la charge la charge fonctionne parce que vous avez non transactionnel lit activé (il l'est par défaut). Il n'est pas dit, désolé, pas de transaction (essentiellement, il crée pour vous faire la lecture, qui se termine immédiatement).
Ainsi, lorsque vous ne l'getName quand il a fait à frapper la base de données, il vous dit "pas de session" parce que la session qui ne charge que l'objet est fermé (il a été fermé immédiatement).
Ce que vous devez faire est de démarrer la transaction au début de la servlet d'appel et de fin à la fin de cette façon quand vous ne le getName la session sera toujours disponible.
Il y a probablement quelque chose au printemps qui va traiter ces plomberie pour vous.
Maintenant j'ai mis à jour ma question inclure un service qui peut être utilisé dans une transaction et inclus un gestionnaire de transaction. Cependant, j'ai toujours l'erreur exactement la même: pas de Session. Comment puis-je obtenir cette session a commencé? Le mettre dans une transaction ne semble pas aider
OriginalL'auteur Michael Wiles