代码之家  ›  专栏  ›  技术社区  ›  ps0604

在Scala的游戏中使用Hibernate“无法投射”对象

  •  1
  • ps0604  · 技术社区  · 7 年前

    当我触摸代码并播放自动编译时,就会出现问题。在代码编译之后,当我运行应用程序时,如果代码调用Hibernate函数,我会得到下面的异常 admin.dates.DateHib cannot be cast to admin.dates.DateHib 哪里 DateHib cannot be cast 错误

    解决方法是重新启动Play,但我不能每次触摸代码都重新启动Play。

    我不确定这与这个问题有什么关系,但我运行的是同一个应用程序Slick 3.1访问MySql。

    有什么想法吗?

     def findLastDayHoliday (month: Int, year: Int) = {
         val session = HibernateUtil.sessionFactoryBank.openSession
         try {
             val query = session.createQuery("from DateHib where month=:month and year=:year")
             query.setMaxResults(1)
             query.setParameter("year", year)
             query.setParameter("month", month)
             val list = query.list.asScala.toList.map(_.asInstanceOf[DateHib])
             if (list.length>0)
                 Some(list(0))
             else
                  None
          }
          catch {
            case e:Exception => throw new Exception ("Failure: " + e.getMessage)
          }
          finally session.close
       }
    

    这是个例外:

    play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[Exception: Failure in findLastDayHoliday: admin.dates.DateHib cannot be cast to admin.dates.DateHib]]
            at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:293)
            at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:220)
            at play.api.GlobalSettings$class.onError(GlobalSettings.scala:160)
            at play.api.DefaultGlobal$.onError(GlobalSettings.scala:188)
            at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:100)
            at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:100)
            at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:99)
            at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:344)
            at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:343)
            at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
    Caused by: java.lang.Exception: Failure in findLastDayHoliday: admin.dates.DateHib cannot be cast to admin.dates.DateHib
            at admin.dates.DateObjDAO.findLastDayHoliday(DateObjDAO.scala:126)
            at ds.formula.process.RunFormula.getLastDayHoliday(RunFormula.scala:665)
            at ds.formula.process.RunFormula.getFromToDates(RunFormula.scala:610)
            at ds.formula.process.RunFormula.run(RunFormula.scala:145)
            at ds.formula.process.RunFormula.doTest(RunFormula.scala:69)
            at ds.formula.process.RunFormula$$anonfun$test$1.apply(RunFormula.scala:61)
            at ds.formula.process.RunFormula$$anonfun$test$1.apply(RunFormula.scala:59)
            at login.Authentication$LoggedAction$$anonfun$invokeBlock$1.apply(LoggedAction.scala:39)
            at login.Authentication$LoggedAction$$anonfun$invokeBlock$1.apply(LoggedAction.scala:34)
            at scala.concurrent.Future$$anonfun$flatMap$1.apply(Future.scala:251)
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Frederic A.    7 年前

    我认为cchantep是对的。每次play重新加载应用程序时,它都使用不同的类加载器。

    1. 您正在使用一些单例,这些单例是使用最初由play创建的类加载器加载的,当play重新加载时,这些单例没有被破坏,这导致了您看到的那种问题。
    2. 您使用了一些应该在重播时关闭并重新启动的服务,但您没有这样做,这导致了与上面第1点相同的问题。

         val list = query.list.asScala.toList.map { e => 
           log.debug("Class loaded with: " + e.getClass.getClassLoader)
           log.debug("Current class loader: " + classOf[DateHib].getClassLoader)
           e.asInstanceOf[DateHib]
         }
    

    我的猜测是,打印的类加载器在您第一次启动应用程序时是相同的,但在播放重新加载后,打印的第一个类加载器没有改变,但第二个类加载器是一个新实例。。。试试看。

    https://www.playframework.com/documentation/2.6.x/ScalaDependencyInjection#Stopping/cleaning-up