Showing all posts tagged slick:

CreationException: Unable to create injector

原因:jdbcとplay-slickが依存性に含まれていると、それぞれがplay.api.db.DBApiを使用するので、競合してエラーとなる。

対策:jdbcの除去

参考:play-framework > [play 2.4.0-RC5 Scala] evolutions and injector error with play-slick

! @6mk485065 - Internal server error, for (GET) [/] ->

play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:

1) A binding to play.api.db.DBApi was already configured at play.api.db.slick.evolutions.EvolutionsModule.bindings(EvolutionsModule.scala:14):
Binding(interface play.api.db.DBApi to ConstructionTarget(class play.api.db.slick.evolutions.internal.DBApiAdapter) in interface javax.inject.Singleton) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1).
  at play.api.db.DBModule.bindings(DBModule.scala:25):
Binding(interface play.api.db.DBApi to ProviderConstructionTarget(class play.api.db.DBApiProvider)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)

1 error]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:165) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:121) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at scala.Option.map(Option.scala:146) ~[scala-library-2.11.6.jar:na]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:121) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:119) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at scala.util.Success.flatMap(Try.scala:230) ~[scala-library-2.11.6.jar:na]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:119) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:111) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) ~[scala-library-2.11.6.jar:na]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) ~[scala-library-2.11.6.jar:na]
    at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1423) ~[na:1.8.0_05]
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) ~[na:1.8.0_05]
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:902) ~[na:1.8.0_05]
    at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1689) ~[na:1.8.0_05]
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1644) ~[na:1.8.0_05]
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157) ~[na:1.8.0_05]
Caused by: com.google.inject.CreationException: Unable to create injector, see the following errors:

1) A binding to play.api.db.DBApi was already configured at play.api.db.slick.evolutions.EvolutionsModule.bindings(EvolutionsModule.scala:14):
Binding(interface play.api.db.DBApi to ConstructionTarget(class play.api.db.slick.evolutions.internal.DBApiAdapter) in interface javax.inject.Singleton) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1).
  at play.api.db.DBModule.bindings(DBModule.scala:25):
Binding(interface play.api.db.DBApi to ProviderConstructionTarget(class play.api.db.DBApiProvider)) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)

1 error
    at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:466) ~[guice-4.0.jar:na]
    at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155) ~[guice-4.0.jar:na]
    at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107) ~[guice-4.0.jar:na]
    at com.google.inject.Guice.createInjector(Guice.java:96) ~[guice-4.0.jar:na]
    at com.google.inject.Guice.createInjector(Guice.java:73) ~[guice-4.0.jar:na]
    at com.google.inject.Guice.createInjector(Guice.java:62) ~[guice-4.0.jar:na]
    at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:126) ~[play_2.11-2.4.1.jar:2.4.1]
    at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:93) ~[play_2.11-2.4.1.jar:2.4.1]
    at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21) ~[play_2.11-2.4.1.jar:2.4.1]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:153) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:150) ~[play-server_2.11-2.4.1.jar:2.4.1]
    at play.utils.Threads$.withContextClassLoader(Threads.scala:21) ~[play_2.11-2.4.1.jar:2.4.1]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:150) ~[play-server_2.11-2.4.1.jar:2.4.1]
    ... 15 common frames omitted

Slick関連リンク

slickでauto incrementを設定する(Play Framework 2.1)

カラムidをauto-incrementにしたいとする。

ポイントは以下の通り。
1.class Userの引数idをOptionでくるむ
2.object UsersのカラムidにO.AutoIncを設定する
3.メソッドautoIncを作成する、この際returining idとすると便利
4.各メソッド(*, autoIncなど)のカラムidにautoIncであることを示す".?"を付加

case class User(id: Option[Int], email: String, name: String, password: String)

object Users extends Table[User]("user") {
lazy val database = Database.forDataSource(DB.getDataSource())
def id = column[String]("id", O.PrimaryKey, O.AutoInc)
def email = column[String]("email")
def name = column[String]("name")
def password = column[String]("password")
def autoInc = id.? ~ email ~ name ~ password <>(User.apply _, User.unapply _) returning id
def * = id.? ~ email ~ name ~ password <>(User.apply _, User.unapply _)
}

これにより、以下を実行するとauto-incrementされたidが返るようになります。
Users.autoInc.insert(User(None, aaa@sample.com, "Noriaki", "secret"))

参考:
http://stackoverflow.com/questions/13114255/getting-autoincrement-values-with-slick-library-in-scala

テーブルのカラム設定

カラム定義の際、名称のあとに、オプションを記載することができます。
Oオブジェクトから呼び出すことができます。

例:
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def email = column[String]("email", O.NotNull)
def name = column[String]("name", O.Default("名無しさん"))
def password = column[String]("password", O.NotNull)

設定できる項目は以下の通り。

【 NotNull, Nullable 】
・明示的に決めたい場合は記述する。
・暗黙的に決めることもできる。その場合は、case classの引数をOption型とする。

【 PrimaryKey 】
・主キーとする。

【 Default[T](defaultValue: T) 】
・情報が存在しなかった場合(None?)にデフォルト値としてdefaultValueを挿入する。

【 DBType(dbType: String) 】
・標準的でないデータベース定義をする場合に用いる(例:DBType("VARCHAR(20)"))。

【 AutoInc 】
・Auto Incrementするように定める。
・データ挿入時に値を返す場合は、必ずこれが設定されているかチェックされる。
  (Auto-Incermentでないカラムを返すことが許されていないデータベースが多いため)。


参考:http://slick.typesafe.com/doc/1.0.0/lifted-embedding.html#tables