I have the following classes. please note the commented-out Role lines.
user model:
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 and 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))
}
}
and a test spec:
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
}
when i run this spec, it succeeds. great.
now i want to add a role to my user. so i created the following Role class:
object Role extends Enumeration{
type Role = Value
val None = Value("NONE")
val Admin = Value("ADMIN")
val Root = Value("ROOT")
}
and uncomment the relevant lines (and add it to any instanciation call), and update the evolutions file (the Role part is stored as a VARCHAR). now, when the spec runs, i get the following exception:
[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)
I tried researching online, but all the Slick samples I found on how to do Enumerations seem like mine, and the injection error does not show up in the Slick context.
any idea?