本文介绍了Scala Play Framework Slick Session的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我正在使用Play 2.2在Scala中创建一个应用程序.我正在使用play-slick 0.5.0.8作为我的MySQL DB连接器.我有以下应用程序控制器:

I'm creating an application in Scala using Play 2.2. I'm using play-slick 0.5.0.8 as my MySQL DB connector. I have the following application controller:

package controllers

import models._
import models.database._

import play.api._
import play.api.mvc._
import play.api.Play.current
import play.api.db.slick._

object Application extends Controller {
  // WORKS:
  def test = DBAction {
    implicit session => Ok(views.html.test(Cameras.findById(1)))
  }

  // DOES NOT WORK:
  def photo = Action {
    val p = PhotoFetcher.fetchRandomDisplayPhoto(someParametersBlah))
    Ok(views.html.photo(p))
  }
}

如您所见,test DBAction可以正常工作,并且可以从数据库中获取照片.不幸的是,photo操作不起作用.

As you can see, the test DBAction works, and it's able to fetch a photo from the DB just fine. Unfortunately, the photo Action does not work.

我的PhotoFetcher.fetchRandomDisplayPhoto(blah)做很多不同的事情.内置于其中的是对Cameras.findById(blah)的调用,该调用应返回一个Camera对象(在test DBAction中有效).但是,使用此配置,我得到以下错误:

My PhotoFetcher.fetchRandomDisplayPhoto(blah) does a bunch of different things. Buried inside of it is a call to Cameras.findById(blah), which should return a Camera object (which works in the test DBAction). However, with this configuration I get the following error:

could not find implicit value for parameter s: slick.driver.MySQLDriver.simple.Session

我曾尝试将photo动作制作成DBAction,就像这样:

I have tried making the photo Action into a DBAction, like so:

def photo = DBAction {
  implicit session => {
    val p = PhotoFetcher.fetchRandomDisplayPhoto(someParametersBlah))
    Ok(views.html.photo(p))
  }
}

但这只会导致相同的丢失会话错误.就像PhotoFetcher不知道隐式会话一样.

But that just results in the same missing session error. It's like PhotoFetcher doesn't know about the implicit session.

我尝试过的另一件事是在PhotoFetcher中导入slick.session.Database.threadLocalSession,但这只会导致以下错误:

The other thing I've tried is importing slick.session.Database.threadLocalSession in my PhotoFetcher, but that only results in the following error:

SQLException: No implicit session available; threadLocalSession can only be used within a withSession block

如果有帮助,这是我的Cameras对象的简化版本:

If it's any help, this is a simplified version of my Cameras object:

package models.database

import models.Format.Format
import scala.slick.driver.MySQLDriver.simple._

case class Camera(id: Long,
                  otherStuff: String)

trait CamerasComponent {
  val Cameras: Cameras

  class Cameras extends Table[Camera]("cameras") {
    def id          = column[Long]("id", O.PrimaryKey, O.AutoInc)
    def otherStuff  = column[String]("otherStuff", O.NotNull)

    def * = id ~ otherStuff <> (Camera.apply _, Camera.unapply _)

    val byId         = createFinderBy(_.id)
    val byOtherStuff = createFinderBy(_.otherStuff)
  }
}

object Cameras extends DAO {
  def insert(camera: Camera)(implicit s: Session) { Cameras.insert(camera) }
  def findById(id: Long)(implicit s: Session): Option[Camera] = Cameras.byId(id).firstOption
  def findByOtherStuff(otherStuff: String)(implicit s: Session): Option[Camera] = Cameras.byOtherStuff(model).firstOption
}

所以,好像我已经在某个地方交叉起来了.现在,我只能直接从Controller DBAction访问我的DAO对象,而不能从其他不同类的内部访问我的DAO对象.任何帮助,将不胜感激.谢谢!

So, it seems as if I've gotten crossed-up somewhere. Right now it's only possible for me to access my DAO objects directly from a Controller DBAction, and not from inside of some different class. Any help would be appreciated. Thanks!

推荐答案

您对PhotoFetcher.fetchRandomDisplayPhoto.fetchRandomDisplayPhoto的定义是否进行隐式会话?

Does your definition of PhotoFetcher.fetchRandomDisplayPhoto.fetchRandomDisplayPhoto take an implicit session?

 // PhotoFetcher
 def fetchRandomDisplayPhoto(args: Blah*)(implicit s: Session) = {
   // ...
   val maybeCam = Cameras.findById(blah) // <- sees the implicit session
   // ...
 }

还是您依赖PhotoFetcher中的threadLocalsession? (fetchRandomDisplayPhoto没有隐式会话参数)?

Or are you relying on a threadLocalsession in PhotoFetcher? (no implicit session argument for fetchRandomDisplayPhoto)?

尽管Slick的threadLocalSession对于快速尝试一些东西很方便,但以后可能会导致混乱和清晰度下降.最好只对所有调用Slick模型的方法使用明确的(implicit s: Session)参数列表.这也玩DBAction很好,让框架可以管理会话.

While Slick's threadLocalSession is handy for quickly trying out stuff, it can lead to confusion and loss of clarity later on. It's best to just use explicit (implicit s: Session) parameter lists for all methods that call your Slick models. This also playswell with DBAction, letting the framework manage sessions.

缺点是您必须在所有方法上都使用(implicit s: Session)-在那里是这样的解决方法: https://github.com/freekh/play-slick/issues/20

The downside is you have to have (implicit s: Session) on all your methods - thereare workarounds like this:https://github.com/freekh/play-slick/issues/20

Scala并不冗长,非常适合重构-因此,我建议您考虑一下关于过桥时要过桥,并使用DBAction进行所有操作做数据库的东西;提供所有调用数据库模型的方法隐式会话,并查看可以为您带来多少里程.

Scala isn't verbose and is very amenable to refactoring - so I'd recommend thinkingabout crossing that bridge when you come to it, and use DBAction for all actionsthat do database stuff; give all methods that call your database models animplicit session, and see how much that mileage that gives you.

这篇关于Scala Play Framework Slick Session的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 21:59