我有以下课程。请注意已注释掉的角色行。
用户模型:
case class User(
uid: Option[Long] = None,
// role: Option[Role.Role] = None,
firstName: String,
lastName: String,
middleName: Option[String] = None,
email: String,
avatarUrl: Option[String],
created: DateTime = DateTime.now,
modified: DateTime = DateTime.now
)
UserComponent和UserDAO:
import javax.inject._
import scala.concurrent.Future
import org.krazykat.whatsupdoc.models.User
import play.api.db.slick.{HasDatabaseConfigProvider, DatabaseConfigProvider}
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import slick.driver.{JdbcProfile, JdbcDriver}
import org.joda.time.DateTime
import com.github.tototoshi.slick.GenericJodaSupport
import java.sql.Time
trait UsersComponent { self: HasDatabaseConfigProvider[JdbcProfile] =>
import driver.api._
object PortableJodaSupport extends GenericJodaSupport(driver.asInstanceOf[JdbcDriver])
import PortableJodaSupport._
// implicit val roleMapper = MappedColumnType.base[Role.Role, String](
// e => e.toString,
// s => Role.withName(s)
// )
class Users(tag: Tag) extends Table[User](tag, "USERS") {
def uid = column[Long]("USER_ID", O.PrimaryKey, O.AutoInc)
// def role = column[Role.Role]("ROLE")
def firstName = column[String]("FIRST_NAME")
def lastName = column[String]("LAST_NAME")
def middleName = column[String]("MIDDLE_NAME")
def email = column[String]("EMAIL")
def avatarUrl = column[String]("AVATAR_URL")
def created = column[DateTime]("CREATED")
def modified = column[DateTime]("MODIFIED")
def * = (uid.?, firstName, lastName, middleName.?, email, avatarUrl.?, created, modified) <> (User.tupled, User.unapply _)
}
}
/**
* @author ehud
*/
@Singleton
class UsersDAO @Inject()(protected val dbConfigProvider: DatabaseConfigProvider) extends UsersComponent with HasDatabaseConfigProvider[JdbcProfile] {
import driver.api._
val users = TableQuery[Users]
def count = db.run(users.length.result)
def getById(uid: Long) =
db.run(users.filter(_.uid === uid).result.headOption)
def insert(user: User) =
db.run((users returning users.map(_.uid)) += user).map(id => id)
def delete(user: User) =
db.run(users.filter(_.uid === user.uid).delete)
def update(uid: Long, user: User) = {
val userToUpdate: User = user.copy(Some(uid))
db.run(users.filter(_.uid === uid).update(userToUpdate))
}
}
和测试规范:
class UsersSpec extends Specification {
def dateIs(date: java.util.Date, str: String) = new java.text.SimpleDateFormat("yyyy-MM-dd").format(date) == str
trait WithDatabaseConfig {
lazy val (driver, db) = {
val dbConfig = DatabaseConfigProvider.get[JdbcProfile](Play.current)
(dbConfig.driver, dbConfig.db)
}
}
"User model" should {
def usersDao(implicit app: Application) = {
val app2UsersDAO = Application.instanceCache[UsersDAO]
app2UsersDAO(app)
}
"be inserted to db correctly" in new WithApplication with WithDatabaseConfig {
import driver.api._
val userInsertresult = Await.result(usersDao.insert(
User(None, "firstname", "lastname", Some("middlename"), "me@me.com", Some("avatar"), DateTime.now, DateTime.now)),
Duration.Inf
)
val count = Await.result(usersDao.count, Duration.Inf)
count mustEqual 1
}
当我运行此规范时,它会成功。大。
现在我想为我的用户添加一个角色。所以我创建了以下Role类:
object Role extends Enumeration{
type Role = Value
val None = Value("NONE")
val Admin = Value("ADMIN")
val Root = Value("ROOT")
}
并取消注释相关行(并将其添加到任何instanciation调用),并更新evolutions文件(Role部分存储为VARCHAR)。现在,当规范运行时,我得到以下异常:
[error] ! be inserted to db correctly
[error] Unable to provision, see the following errors:
[error]
[error] 1) Error injecting constructor, java.lang.NullPointerException
[error] at UsersDAO.<init>(UsersDAO.scala:59)
[error] at UsersDAO.class(UsersDAO.scala:59)
[error] while locating UsersDAO
[error]
[error] 1 error (InjectorImpl.java:1025)
[error] com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1025)
[error] com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051)
[error] play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:321)
[error] play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:316)
[error] play.api.Application$$anonfun$instanceCache$1.apply(Application.scala:234)
[error] play.api.Application$$anonfun$instanceCache$1.apply(Application.scala:234)
[error] play.utils.InlineCache.fresh(InlineCache.scala:69)
[error] play.utils.InlineCache.apply(InlineCache.scala:55)
我尝试在线进行研究,但是我发现的关于如何进行枚举的所有Slick样本看起来都像我的,并且注入错误没有出现在Slick上下文中。
任何想法?
答案 0 :(得分:2)
此处的问题是您尝试使用driver.api.MappedColumnType
特征中HasDatabaseConfigProvider
特征的UsersComponent
。
但是在UsersComponent
初始化驱动程序尚未注入的那一刻,这会导致NPE。
您可以将roleMapper
val lazy
或val
更改为def
:
implicit lazy val roleMapper = ...
OR
implicit def roleMapper = ...
答案 1 :(得分:0)
你选择- (NSFetchedResultsController *)fetchedResultsController
{
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
if (_fetchedResultsController != nil)
{
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Favourites" inManagedObjectContext:managedObjectContext];
fetchRequest.entity = entity;
NSPredicate *d = [NSPredicate predicateWithFormat:@"title != nil"];
[fetchRequest setPredicate:d];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:NO];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sort];
fetchRequest.fetchBatchSize = 20;
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
的任何特殊原因?如果是的话,我无法帮助你,但我可以建议使用密封的特征+案例对象+ sealerate。
为Enumeration
创建随播广告并描述case class User
Role
将object User {
sealed trait Role
case object None extends Role
case object Root extends Role
case object Admin extends Role
// A bit messy stuff to convert Role to String and back
def s = sealerate.values[Role].foldLeft(Map[String, Role]()) { case (m, f) ⇒ m.updated(f.toString, f) }
implicit val roleColumnType: JdbcType[Role] with BaseTypedType[Role] = MappedColumnType.base[Role, String](_.toString, s)
}
添加到role
案例类
User
将case class User(
uid: Option[Long] = None,
role: Option[User.Role] = User.None,
firstName: String,
lastName: String,
middleName: Option[String] = None,
email: String,
avatarUrl: Option[String],
created: DateTime = DateTime.now,
modified: DateTime = DateTime.now
)
添加到role
表格
Users
全部:)
Scala枚举here的简要说明。