对象'无法投射'在Play for Scala中使用Hibernate

时间:2017-08-18 04:46:37

标签: scala hibernate playframework playframework-2.0

我在Play for Scala 2.5中运行Hibernate 5.x. Hibernate访问SAP Hana数据库。

当我触摸代码并自动编译时会出现问题。在代码编译之后,当我运行应用程序时,如果代码调用Hibernate函数,我得到admin.dates.DateHib cannot be cast to admin.dates.DateHib下面的异常,其中DateHib是一个Hibernate注释类。请注意,我既不会更改Hibernate对象,也不会更改使用Hibernate对象的函数。但是,当我在编辑后运行代码时,我收到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 个答案:

答案 0 :(得分:1)

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

我看到可能发生的两件事:

  1. 你正在使用一些最初使用类加载器加载的单例,当游戏重新加载时,这些单例不会被破坏,导致你看到的那种问题。
  2. 您使用了一些应该关闭的服务,并在播放重新加载时重新启动,但是您没有,这导致与上面第1点相同的问题。
  3. 但首先,让我们确保以上是正确的,看看如何更准确地诊断:我会在失败的代码中添加日志条目来打印不同对象中使用的类加载器。

         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