play-silhouette-seed 4.0.0 でのsignup時のmysqlへのinsert
play-silhouette-seed 4.0.0 を使ったsignupの際に、同時にmysqlへinsertしたいと考えているのですが、エラーは出ていないものの、mysqlのcolumnには記録されていない状況です。(5/20 追加; insertした際のログも出ないので、sql文が実行されていないと思われます)
なお手を加えるにあたり、以前いただいたご回答を参考にさせていただいています。
ProvisionException: Unable to provision / Error injecting constructor, java.lang.NullPointerException
関連するファイルは以下になります。
flywayを使ったmigration ( V1__create_tables.sql )
-- DROP TABLE IF EXISTS `customer1`;
CREATE TABLE `customer1` (
`pk` BIGINT NOT NULL AUTO_INCREMENT,
`id` BIGINT NOT NULL,
`name` VARCHAR(256) NOT NULL,
`email` VARCHAR(64) NOT NULL,
`password` VARCHAR(64) NOT NULL,
PRIMARY KEY(`pk`),
UNIQUE(`id`)
);
(application.conf) DB関連部分のみ載せてあります
include "silhouette.conf"
play.modules {
enabled += "modules.BaseModule"
enabled += "modules.JobModule"
enabled += "modules.SilhouetteModule"
enabled += "play.api.libs.mailer.MailerModule"
disabled += "com.mohiva.play.silhouette.api.actions.SecuredErrorHandlerModule"
disabled += "com.mohiva.play.silhouette.api.actions.UnsecuredErrorHandlerModule"
enabled += "scalikejdbc.PlayModule"
enabled += "scalikejdbc.PlayDBApiAdapterModule"
#enabled += "play.modules.swagger.SwaggerModule"
enabled += "org.flywaydb.play.PlayModule"
play.modules.disabled += "play.api.db.DBModule"
}
db {
default.driver="org.mariadb.jdbc.Driver"
default.url="jdbc:mariadb://127.0.0.1:3306/spetstore?characterEncoding=utf8"
default.username= admin
default.password= admin
default.poolInitialSize = 10
default.poolMaxSize = 10
default.poolValidationQuery = "select 1 as one"
}
scalikejdbc {
global {
loggingSQLAndTime.enabled = true
loggingSQLAndTime.singleLineMode = true
loggingSQLAndTime.logLevel = DEBUG
loggingSQLAndTime.warningEnabled = true
loggingSQLAndTime.warningThresholdMillis = 5
loggingSQLAndTime.warningLogLevel = warn
}
}
(signupcontroller.scala) 左のファイルは手を加えていません。
(signupform.scala)
package forms
import play.api.data.Form
import play.api.data.Forms._
/**
* The form which handles the sign up process.
*/
object SignUpForm {
/**
* A play framework form.
*/
val form = Form(
mapping(
"firstName" -> nonEmptyText,
"lastName" -> nonEmptyText,
"email" -> email,
"password" -> nonEmptyText
)(Data.apply)(Data.unapply)
)
/**
* The form data.
*
* @param firstName The first name of a user.
* @param lastName The last name of a user.
* @param email The email of the user.
* @param password The password of the user.
*/
case class Data(
firstName: String,
lastName: String,
email: String,
password: String)
// 以下の一文を追加. dbへのinsert
def insert(data: Data): Unit = SignUpFormSupport.insert(data)
}
(signupformsupport.scala) 自身で追加したファイル。 mysqlへのinsertにはscalikejdbcを使っています。
package forms
import java.util.UUID
import javax.inject.Inject
import com.mohiva.play.silhouette.api._
import com.mohiva.play.silhouette.api.repositories.AuthInfoRepository
import com.mohiva.play.silhouette.api.services.AvatarService
import com.mohiva.play.silhouette.api.util.PasswordHasherRegistry
import com.mohiva.play.silhouette.impl.providers._
import models.User
import models.services.{ AuthTokenService, UserService }
import org.webjars.play.WebJarsUtil
import play.api.i18n.{ I18nSupport, Messages }
import play.api.libs.mailer.{ Email, MailerClient }
import play.api.mvc._
import utils.auth.DefaultEnv
import scala.concurrent.{ ExecutionContext, Future }
import com.typesafe.config.ConfigFactory
import java.sql.Connection
import scalikejdbc._
import scalikejdbc.SQLInterpolation._
import forms.SignUpForm.Data
object SignUpFormSupport {
/** 登録 */
def insert(data: Data): Unit = {
try {
DB localTx { implicit session =>
import data._
val id = System.currentTimeMillis()
sql"""insert into customer1 (id, `name`, email, `password`)
|values ($id, ${firstName + lastName}, $email, $password)"""
.stripMargin
.update
.apply()
}
} catch {
case e: Exception => e.printStackTrace()
}
}
}
signupform.scala で、objectの中に case class が入っているのに対し、signupformsupport.scala のimport文が正しく書けているかもわかりません。
ご回答いただければ幸いです。
5/20 その後engineがInnoDBになっていないのかどうかも確認しましたが、問題なくdefaultになっているようです。
一つ気になっている点として、上記のファイルはcontrollerではないですが、前回同様の実装をした折はcontrollerでした。ただフォームで得た変数を渡すだけのメソッドしかmodelsのファイルには記していないため、controllerである必要はないだろうと考えているのですが、その点はいかがでしょうか。(もっとも、フォームのファイルをcontrollerにしようとすると、signupcontroller.scalaのほうにフォームを記さなくては無くなりそうで、seedの構成を壊してしまいそうです。)
またその後試しにSignUpController.scalaのほうに、
import forms.SignUpForm._
// dbへのinsert
def insert(data: Data): Unit = SignUpFormSupport.insert(data)
を加え、SignUpForm.scalaの方をコメントアウトしてみたものの、やはり状況に変化はありませんでした。
5/21 ドキュメント( https://www.playframework.com/documentation/ja/2.4.x/ScalaForms) に、
email: scala.String にマッピングされ、電子メールの正規表現を使用します。
の一文があり、
val email2 = email.toString
sql"""insert into customer1 (id, `name`, email, `password`)
|values ($id, ${firstName + lastName}, $email2, $password)"""
.stripMargin
.update
.apply()
としてみたものの、やはり変化はありません。また、ログを見ると、
[info] application - Creating Pool for datasource 'default'
[info] p.a.d.DefaultDBApi - Database [default] connected at jdbc:mariadb://127.0.0.1:3306/spetstore?characterEncoding=utf8
[debug] application - Directory for migration files found. db/migration/default
[info] play.api.Play - Application started (Dev)
とあるため、当たり前ではありますがmariadb自体は動いており、migrationもできている状況です。
5/23 解決しました。
以下のようにSignUpController.scalaを書き換えることで無事挿入できました。
case None =>
//(中略)
SignUpFormSupport.insert(data)