1

遅延ロードされたエンティティを持つ 1 つのコントローラーのみに問題があります (トランザクションが開始およびコミットされています。スタック トレースを参照してください)。

17:56:46,084 DEBUG HibernateTransactionManager:438 - Found thread-bound Session [org.hibernate.impl.SessionImpl@6b204e88] for Hibernate transaction
17:56:46,085 DEBUG HibernateTransactionManager:471 - Participating in existing transaction
17:56:46,085 DEBUG HibernateTransactionManager:438 - Found thread-bound Session [org.hibernate.impl.SessionImpl@6b204e88] for Hibernate transaction
17:56:46,085 DEBUG HibernateTransactionManager:471 - Participating in existing transaction
Hibernate: select preference0_.id as id66_, preference0_.name as name66_, preference0_.value as value66_, preference0_.default_value as default4_66_, preference0_.updated_at as updated5_66_ from preferences preference0_ where preference0_.name='scheduleInterval'
17:56:46,086 DEBUG GooGooStatementCache:457 - cxnStmtMgr.statementSet( com.mysql.jdbc.JDBC4Connection@5ec60ee2 ).size(): 21
17:56:46,086 DEBUG GooGooStatementCache:196 - checkoutStatement: com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 111; checked out: 1; num connections: 10; num keys: 111
17:56:46,087 DEBUG GooGooStatementCache:271 - checkinStatement(): com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 111; checked out: 0; num connections: 10; num keys: 111
17:56:46,089 FATAL app:79 - service
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
    at com.model.User_$$_javassist_76.getName(User_$$_javassist_76.java)
    at com.model.json.ScheduleItemWrapper.wrap(ScheduleItemWrapper.java:55)
    at com.web.controllers.ajax.Model.wrap(Model.java:127)
    at com.web.controllers.ajax.Model.toJSON(Model.java:165)
    at com.web.controllers.ajax.Model.getContent(Model.java:51)
    at com.web.controllers.ajax.BasicAction.execute(BasicAction.java:27)
    at com.web.HibernateServlet.doService(HibernateServlet.java:113)
    at com.web.HibernateServlet.service(HibernateServlet.java:66)
    at sun.reflect.GeneratedMethodAccessor200.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:695)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
    at com.levitech.web.controllers.schedule.ScheduleList$$EnhancerByCGLIB$$4a7ae33e.service(<generated>)
    at com.levitech.web.RequestDispatcher.service(RequestDispatcher.java:63)
    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:127)
    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:859)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:662)
17:56:46,090 DEBUG HibernateTransactionManager:753 - Initiating transaction commit
17:56:46,090 DEBUG HibernateTransactionManager:653 - Committing Hibernate transaction on Session [org.hibernate.impl.SessionImpl@6b204e88]
17:56:46,091 DEBUG HibernateTransactionManager:735 - Closing Hibernate Session [org.hibernate.impl.SessionImpl@6b204e88] after transaction
17:56:46,091 DEBUG SessionFactoryUtils:800 - Closing Hibernate Session

モデル (ScheduleItem および User) とその休止状態のマッピング

public class ScheduleItem {
  private Integer id;
  ....
  private User user;

}

public class User {
  private Integer id;
  ...
  private String name;

}

<class 
    name="ScheduleItem" 
    table="schedule_item"
>

    <cache usage="read-write"/>


    <id
        name="id"
        type="integer"
        column="id"
    >
    <generator class="identity" />
    </id>
    <many-to-one name="user" column="user_id" lazy="proxy"></many-to-one>
</class>

<class 
    name="ScheduleItem" 
    table="schedule_item"
>

    <cache usage="read-write"/>


    <id
        name="id"
        type="integer"
        column="id"
    >
    <generator class="identity" />
    </id>
    <property name="name" column="name" type="string" />
</class>

犯人を見つけました。OpenSessionViewFilter は、別のセッションまたはセッション ファクトリを使用しています。

これが私のSpring構成とweb.xmlです(何が間違っていますか?):

web.xml の一部:

<filter>
      <filter-name>hibernateFilter</filter-name>
      <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
      <init-param>
         <param-name>sessionFactoryBeanName</param-name>
         <param-value>sessionFactory</param-value>         
      </init-param>      
   </filter>

   <filter-mapping>
     <filter-name>hibernateFilter</filter-name>
     <url-pattern>/app/s/*</url-pattern>
   </filter-mapping> 

Spring Config の一部:

<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
     <property name="driverClass" value="${db.driver}"/>
     <property name="jdbcUrl" value="${db.url}"/>
     <property name="user" value="${db.user}"/>
     <property name="password" value="${db.pass}"/>

       <!-- Pool properties -->
     <property name="minPoolSize" value="5" />
     <property name="maxPoolSize" value="100" />
     <property name="acquireIncrement" value="5" />
     <property name="maxStatements" value="200" />
     <property name="idleConnectionTestPeriod" value="120" />
     <property name="maxIdleTime" value="1800" />

  </bean>

      <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource"></property>
         <property name="mappingLocations" value="classpath*:com/model/hbm/**/*.hbm.xml" />

    <property name="hibernateProperties">
      <value>
        hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
        hibernate.show_sql=true
        hibernate.cache.region.factory_class=net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory
        hibernate.cache.use_query_cache=true
        hibernate.cache.use_second_level_cache=true
      </value>
    </property>
      </bean>

      <bean id="transactionManager"
                class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
      </bean>
4

3 に答える 3

2

ログから、この例外が発生したときにセッションがまだ開いているように見えます。このような例外が発生するもう 1 つのシナリオは、行がデータベースに存在しない場合です。

User user = session.load(User.class, 1000); // Create a proxy
user.getName(); // This would throw lazy initialization exception if row doesn't exist

これにつながるもう 1 つのシナリオは、デタッチされたオブジェクトの操作です。ScheduleItem を取得して HTTPSession 変数として保存した場合。別のリクエストで取得してからプロキシにアクセスしようとすると、同じ例外が発生します。オブジェクトのロードに使用されたセッションが閉じられました。その場合は、オブジェクトを使用する前に、オブジェクトを新しいセッション (マージ、更新、またはロック) に再アタッチする必要があります。

于 2013-05-30T02:15:17.803 に答える
2

あなたの問題には複数の解決策があります:

  • 最も簡単なのは、Spring のOpenSessionInViewFilter. このフィルタを に追加してweb.xml、リクエストをフィルタリングするように設定するだけです。このフィルターは、フィルターで Hibernate セッションを開いたり閉じたりするため、ページのレンダリング中にセッションが開かれます。

  • 一部の人々は、それOpenSessionInViewFilterは優れた設計に反していると考えており、ビジネス ロジックをプレゼンテーション層に混在させています。そう思う場合は、参照されているオブジェクトをクエリで取得します (たとえばjoin fetch、HQL で使用して)。

于 2013-05-28T22:13:15.913 に答える
-1

次のことを試みることができます。

  • コレクションを積極的に読み込みます。
  • コレクションを終了する前に、それぞれの getter メソッドを呼び出してコレクションを初期化しますHibernate.initialize(rtn.getUserRoles());

これは、セットアップで何が最適に機能するかに応じて、基本的に同じアプローチの 2 倍です。セッションを終了する前に、完全なエンティティをロードして、エンティティを古いものから切り離し、新しいセッションに問題なく再接続できるようにします。あなたがしていることは、セッションを離れる前にプロキシを初期化して、セッションコンテキストから離れたときにコレクションが確実に利用できるようにすることです。

于 2013-05-29T06:53:15.907 に答える