2009-07-30 21 views
4

私は春に新しくなったので、Mac上のTomcatサーバーにSpring 3.0M3を置き、Eclipseプロジェクトを作成し、Hello Worldを完成しました。オブジェクトはHibernateで永続化されます。私はMySQLサーバ上でUserテーブルを作成し、すべてのgetterとsetterを持つUserオブジェクトを作成しました(ここでObjective-CからJavaをキューに入れ、動的プロパティを追加したいと思っています。 UserDaoオブジェクトを参照してUserを保存し、Beanの設定を行いました。それはかなりうまくいく...セッションが初期化されていないことを除いて。どうしてこれなの?これらの資格情報を使用してこのコンピュータから正常にデータベースにアクセスできます。Hibernate/Spring3:プロキシを初期化できませんでした - セッションなし

これはたぶん普通の初心者用のものだとわかりますが、グーグルではHibernate 2から3に移行する途中でセッションを失っている人がいました。そして、セッションが決してできないと私が言うことができる限り。ここで

は私のエラーです:ここで

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 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> 

は私のUserクラスです:

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です:

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のインタフェースは

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です:

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; 
    } 

} 

私はあなたが私が使用することができますいくつかの良いヒントを持っていることを望みます。 - )私が間違った/非春のやり方をしていると感じているコードに他に何かがあるなら、私はtについて聞きたいと思う帽子も同様です。

乾杯

Nik 
+0

更新された回答を見る – skaffman

答えて

8

は、あなたのスタックトレースを使用すると、UserDaoのために掲載のサンプルコードと一致しません。トレースにはUserDao.lookupUser()からHibernateTemplate.initialize()が呼び出されていますが、サンプルコードではそのようなことは行われていません(同様に、initialize()はここで呼び出されるべきではありません)。

編集:OK、新しいスタックトレースでは、単にhibernateTemplate.load()を呼び出すことに問題があるようですが、特定の状況でのみ使用する必要があります(これはその1つではありません)。あなたはおそらくhibernateTemplate.get()と呼ぶべきです。

+0

おっと、私は質問を書いている間にちょっとしたクリーニングを試みた。私は再びそれをクラッシュさせてstacktraceを更新しましょう:-) – niklassaers

+0

Stacktrace updated :-) – niklassaers

+0

Aha !!!どうもありがとうございました!!!!私が追加しなければならない本(非常に優れている)、190ページのActinoの春は明示的に言ったので、私はそれを使用しました。おそらくこれは本が書かれて以来変更されているでしょう。 .load()は今どういう意味ですか、それは.get()とどう違うのですか?今はすべてが素晴らしいです。どうもありがとうございました。 – niklassaers

3

dao呼び出しを実行すると、オブジェクトが読み込まれます。 Loadはデータベースにヒットせず、オブジェクトが必要なときだけデータベースにヒットするようにオブジェクトにプロキシを返します。

ロード前にトランザクションを開始しませんでした。非トランザクション読み取りがオンになっているため(デフォルトでオンになっているため)、ロードが機能します。申し訳ありませんが、トランザクションはありません(基本的には、あなたが読んで、すぐに終了するものを作成します)。

したがって、実際にデータベースにアクセスする必要があるときにgetNameを実行すると、そのオブジェクトをロードしたセッションが閉じられているため(すぐに閉じられたため)、「セッションがありません」というメッセージが表示されます。

これを修正するために必要なことは、サーブレットコールの開始時にトランザクションを開始し、最後にトランザクションを開始することです。getNameを実行すると、セッションは引き続き使用可能になります。

おそらく、あなたのためにこの配管を処理する春の何かがあります。

+0

あなたは、非トランザクションフローを使用することができないと言いますか? 第二に、私は春が私のためにこれを処理するという印象を受けました。結局のところ、それはデータソース、sessionFactoryとエンティティを持っていますか? 第3に、遅延フェッチを無効にしたので、プロキシオブジェクトを作成するだけでなく、そのオブジェクトも設定する必要があります。 – niklassaers

+0

今質問を更新して、トランザクションで使用できるサービスとトランザクションハンドラを含めるようにしました。しかし、私はまだまったく同じエラーが発生します:セッションなし。このセッションを開始するにはどうすればよいですか?それを取引に入れても助けにならなかった – niklassaers

関連する問題