您好我遇到了一个UnexpectedNullableFound的问题。列可以返回空值,但我将其映射(如下所示)作为选项,因此不应该导致问题。这适用于我从该表中获取的其他字段。如果我删除' pe.company AS admin_company'和代码中的相关映射,我没有任何问题。
如果admin_company为null,我会遇到此问题。如果没有,它执行得很好。
我已经阅读了很多相关问题,但是在这里找不到任何解决方案。
有关于此的任何想法吗?感谢
play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[RuntimeException: ColumnName(test_users.company,Some(admin_company))]]
at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:265)
at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:191)
at play.api.GlobalSettings$class.onError(GlobalSettings.scala:179)
at play.api.DefaultGlobal$.onError(GlobalSettings.scala:212)
at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:94)
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3.applyOrElse(PlayDefaultUpstreamHandler.scala:266)
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3.applyOrElse(PlayDefaultUpstreamHandler.scala:262)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:344)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:343)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
at play.api.libs.iteratee.Execution$trampoline$.executeScheduled(Execution.scala:109)
at play.api.libs.iteratee.Execution$trampoline$.execute(Execution.scala:71)
at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:40)
at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:248)
at scala.concurrent.Promise$class.complete(Promise.scala:55)
at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:153)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:23)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:397)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
Caused by: java.lang.RuntimeException: ColumnName(test_users.company,Some(admin_company))
at scala.sys.package$.error(package.scala:27)
at anorm.SqlRequestError$class.toFailure(Anorm.scala:20)
at anorm.UnexpectedNullableFound.toFailure(Anorm.scala:37)
at anorm.Sql$$anonfun$asTry$2$$anonfun$apply$7.apply(Anorm.scala:303)
at anorm.Sql$$anonfun$asTry$2$$anonfun$apply$7.apply(Anorm.scala:303)
at anorm.SqlResult$class.fold(SqlResult.scala:23)
at anorm.Error.fold(SqlResult.scala:31)
at anorm.Sql$$anonfun$asTry$2.apply(Anorm.scala:303)
at anorm.Sql$$anonfun$asTry$2.apply(Anorm.scala:303)
at scala.util.Success.flatMap(Try.scala:230)
at anorm.Sql$.asTry(Anorm.scala:303)
at anorm.WithResult$class.as(SqlResult.scala:120)
at anorm.SimpleSql.as(SimpleSql.scala:6)
at com.company.test.user.service.testUserService$$anonfun$findByEmail$1.apply(testUserService.scala:229)
at com.company.test.user.service.testUserService$$anonfun$findByEmail$1.apply(testUserService.scala:214)
at play.api.db.DefaultDatabase.withConnection(Databases.scala:155)
at play.api.db.DefaultDatabase.withConnection(Databases.scala:149)
at play.api.db.DB$.withConnection(DB.scala:61)
at com.company.test.user.service.testUserService.findByEmail(testUserService.scala:214)
at com.company.test.controllers.testLoginController.checkPasswordAndSaveUserInSession(testLoginController.scala:128)
这是相关代码:
def findByUserId(userId: Long): TestUser = {
DB.withConnection { implicit connection =>
SQL"""
SELECT s.test_users_id, s.test_users_email AS user_email, s.test_users_first_name, s.test_users_second_name, s.company, s.useas, s.Stripe_CUSTOMER_ID,
s.is_invoice_customer, s.test_users_invoice_email,
s.password_hash, s.salt, s.invoice_address,
s.time_zone, s.last_payment_date AS user_last_payment_date, s.sign_up_date, s.test_role AS user_test_role, s.num_seats, (SELECT COUNT(*) FROM test_users_paid_for WHERE test_users_admin_id = $userId) AS paid_for_seats,
s.syndication_access_manager, p.test_users_admin_id, pe.last_payment_date AS admin_last_payment_date, pe.test_role AS admin_test_role,
s.first_payment_date AS first_payment_date, pe.first_payment_date AS admin_first_payment_date, pe.test_users_email AS admin_email, pe.company AS admin_company, s.utm_source, s.utm_medium, s.utm_campaign, s.sf_exec, s.bounced_email,
s.vat_number
FROM test_users AS s
LEFT JOIN test_users_paid_for AS p ON email_users_email = s.test_users_email
LEFT JOIN test_users AS pe ON p.test_users_admin_id = pe.test_users_id
WHERE s.test_users_id = $userId
""".as(simple.single)
}
}
val customer = {
get[Long]("test_users_id") ~
get[Option[Long]]("test_users_admin_id") ~
get[String]("company") ~
getAliased[Option[String]]("admin_company") ~
getAliased[Option[DateTime]]("first_payment_date") ~
getAliased[Option[DateTime]]("admin_first_payment_date") ~
getAliased[Option[String]]("user_test_role") ~
getAliased[Option[String]]("admin_test_role") map {
case testUserId ~ testUsersAdminId ~ company ~ adminCompany ~ firstPaymentDate ~ adminFirstPaymentDate ~ testRole ~ admintestRole =>
if(testUsersAdminId.isDefined){
getCompanyCustomer(testUsersAdminId, adminCompany, adminFirstPaymentDate, admintestRole)
} else {
getCompanyCustomer(Some(testUserId), Some(company), firstPaymentDate, testRole)
}
}
}
def getCompanyCustomer(testUsersAdminId: Option[Long], adminCompany: Option[String], adminFirstPaymentDate: Option[DateTime], admintestRole: Option[String]): Option[CompanyCustomer] = {
for {
id <- testUsersAdminId
company <- adminCompany
firstPaymentDate <- adminFirstPaymentDate
testRole <- admintestRole
} yield CompanyCustomer(id, company, firstPaymentDate, testRole)
}
val simple = {
get[Long]("test_users_id") ~
getAliased[String]("user_email") ~
get[String]("test_users_first_name") ~
get[String]("test_users_second_name") ~
get[String]("company") ~
customer ~
get[String]("useas") ~
get[Option[String]]("Stripe_CUSTOMER_ID") ~
get[Boolean]("is_invoice_customer") ~
get[Option[String]]("test_users_invoice_email") ~
get[Array[Byte]]("password_hash") ~
get[Array[Byte]]("salt") ~
get[String]("invoice_address") ~
get[Option[String]]("time_zone") ~
getAliased[DateTime]("user_last_payment_date") ~
get[DateTime]("sign_up_date") ~
getAliased[Option[String]]("user_test_role") ~
get[Option[Int]]("num_team") ~
get[Int]("paid_for_team") ~
get[Option[Long]]("test_users_admin_id") ~
getAliased[Option[DateTime]]("admin_last_payment_date") ~
getAliased[Option[String]]("admin_test_role") ~
getAliased[Option[DateTime]]("first_payment_date") ~
getAliased[Option[String]]("admin_email") ~
getAliased[Option[DateTime]]("admin_first_payment_date") ~
getAliased[Option[String]]("utm_source") ~
getAliased[Option[String]]("utm_medium") ~
getAliased[Option[String]]("utm_campaign") ~
getAliased[Option[String]]("sf_exec") ~
get[Option[Long]]("access_manager") ~
get[Option[String]]("vat_number") ~
getAliased[Boolean]("bounced_email") map {
case testUsersId ~ userEmail ~ testUsersFirstName ~ testUsersSecondName
~ company ~ adminCustomer ~ useAs ~ stripeCustomerId ~ isInvoiceCustomer ~ secondContactEmail ~ passwordHash ~ salt ~
invoiceAddress ~ timeZone ~ lastPaymentDate ~ signUpDate ~ testRole ~ numteam ~ paidForteam ~ testUsersAdminId ~ adminLastPaymentDate ~ admintestRole ~ firstPaymentDate ~
adminEmail ~ adminFirstPaymentDate ~ utmSource ~ utmMedium ~ utmCampaign ~ sfExec ~ syndicationAccessManagerId ~ vatNumber ~ bouncedEmail =>
testUser(testUsersId, userEmail, testUsersFirstName,
testUsersSecondName, company, adminCustomer, useAs, invoiceAddress,
stripeCustomerId,
isInvoiceCustomer,
secondContactEmail,
passwordHash.toVector, salt.toVector,
teamLastPaymentDate(lastPaymentDate, adminLastPaymentDate, testUsersAdminId, stripeCustomerId), new DateTime(signUpDate, DateTimeZone.UTC),
testRoleFromTeam(testRole, testUsersAdminId, stripeCustomerId, admintestRole), paidByOtherUser(testUsersAdminId, stripeCustomerId), numteam.getOrElse[Int](0), //
getSeatCount(paidForteam), timeZone.flatMap(getSafeTimeZone),
firstPaymentDateFromTeam(testUsersAdminId, stripeCustomerId, firstPaymentDate, adminFirstPaymentDate), adminEmail, utmSource, utmMedium, utmCampaign,
sfExec, syndicationAccessManagerId, vatNumber, bouncedEmail)
}
}
答案 0 :(得分:2)
我的问题的解决方案是将所有别名更改为大写。现在使用Anorm 2.4
可以正常使用我的新代码如下,它还包括一些重构,但大致相同。
val simple = {
get[Long]("test_users_id") ~
getAliased[String]("USER_EMAIL") ~
get[String]("test_users_first_name") ~
get[String]("test_users_second_name") ~
getAliased[String]("USER_COMPANY") ~
get[String]("useas") ~
get[Option[String]]("Stripe_CUSTOMER_ID") ~
get[Boolean]("is_invoice_customer") ~
get[Option[String]]("test_users_invoice_email") ~
get[Array[Byte]]("password_hash") ~
get[Array[Byte]]("salt") ~
get[String]("invoice_address") ~
get[Option[String]]("time_zone") ~
getAliased[DateTime]("USER_LAST_PAYMENT_DATE") ~
get[DateTime]("sign_up_date") ~
getAliased[Option[String]]("USER_SPIKE_ROLE") ~
get[Option[Int]]("num_team") ~
get[Int]("paid_for_team") ~
get[Option[Long]]("test_users_admin_id") ~
getAliased[Option[DateTime]]("ADMIN_LAST_PAYMENT_DATE") ~
getAliased[Option[String]]("ADMIN_SPIKE_ROLE") ~
getAliased[Option[DateTime]]("FIRST_PAYMENT_DATE") ~
getAliased[Option[String]]("ADMIN_EMAIL") ~
getAliased[Option[DateTime]]("ADMIN_FIRST_PAYMENT_DATE") ~
getAliased[Option[String]]("utm_source") ~
getAliased[Option[String]]("utm_medium") ~
getAliased[Option[String]]("utm_campaign") ~
getAliased[Option[String]]("sf_exec") ~
get[Option[Long]]("syndication_access_manager") ~
get[Option[String]]("vat_number") ~
get[Boolean]("bounced_email") ~
getAliased[Option[String]]("ADMIN_COMPANY") map {
case testUsersId ~ userEmail ~ testUsersFirstName ~ testUsersSecondName
~ company ~ useAs ~ stripeCustomerId ~ isInvoiceCustomer ~ xeroContactEmail ~ passwordHash ~ salt ~
invoiceAddress ~ timeZone ~ lastPaymentDate ~ signUpDate ~ testRole ~ numTeam ~ paidForTeam ~ testUsersAdminId ~ adminLastPaymentDate ~ adminTestRole ~ firstPaymentDate ~
adminEmail ~ adminFirstPaymentDate ~ utmSource ~ utmMedium ~ utmCampaign ~ sfExec ~ syndicationAccessManagerId ~ vatNumber ~ bouncedEmail ~ adminCompany =>
TestUser(testUsersId, userEmail, testUsersFirstName,
testUsersSecondName, company, useAs, invoiceAddress,
stripeCustomerId,
isInvoiceCustomer,
xeroContactEmail,
passwordHash.toVector, salt.toVector,
teamLastPaymentDate(lastPaymentDate, adminLastPaymentDate, testUsersAdminId, stripeCustomerId), new DateTime(signUpDate, DateTimeZone.UTC),
testRoleFromTeam(testRole, testUsersAdminId, stripeCustomerId, adminTestRole), paidByOtherUser(testUsersAdminId, stripeCustomerId), numTeam.getOrElse[Int](0), //
getSeatCount(paidForTeam), timeZone.flatMap(getSafeTimeZone),
firstPaymentDateFromTeam(testUsersAdminId, stripeCustomerId, firstPaymentDate, adminFirstPaymentDate), adminEmail, utmSource, utmMedium, utmCampaign,
sfExec, syndicationAccessManagerId, vatNumber, getCompanyCustomer(testUsersAdminId, adminCompany, adminFirstPaymentDate, adminTestRole, testUsersId, company, firstPaymentDate, testRole), bouncedEmail)
}
}
def createCompanyCustomer(testUsersAdminId: Option[Long], adminCompany: Option[String], adminFirstPaymentDate: Option[DateTime], adminTestRole: Option[String]): Option[NewsWhipCustomer] = {
for {
id <- testUsersAdminId
company <- adminCompany
firstPaymentDate <- adminFirstPaymentDate
testRole <- adminTestRole
} yield NewsWhipCustomer(id, company, firstPaymentDate, testRole)
}
def getCompanyCustomer(testUsersAdminId: Option[Long], adminCompany: Option[String], adminFirstPaymentDate: Option[DateTime], adminTestRole: Option[String], testUserId: Long, company: String, firstPaymentDate: Option[DateTime], testRole: Option[String]): Option[NewsWhipCustomer] = {
if (testUsersAdminId.isDefined) {
createCompanyCustomer(testUsersAdminId, adminCompany, adminFirstPaymentDate, adminTestRole)
} else {
createCompanyCustomer(Some(testUserId), Some(company), firstPaymentDate, testRole)
}
}
def findByUserId(userId: Long): TestUser = {
DB.withConnection { implicit connection =>
SQL"""
SELECT s.test_users_id, s.test_users_email AS USER_EMAIL, s.test_users_first_name, s.test_users_second_name, s.company AS USER_COMPANY, s.useas, s.Stripe_CUSTOMER_ID,
s.is_invoice_customer, s.test_users_invoice_email,
s.password_hash, s.salt, s.invoice_address,
s.time_zone, s.last_payment_date AS USER_LAST_PAYMENT_DATE, s.sign_up_date, s.test_role AS USER_SPIKE_ROLE, s.num_team, (SELECT COUNT(*) FROM test_users_paid_for WHERE test_users_admin_id = $userId) AS paid_for_team,
s.syndication_access_manager, p.test_users_admin_id, pe.last_payment_date AS ADMIN_LAST_PAYMENT_DATE, pe.test_role AS ADMIN_SPIKE_ROLE,
s.FIRST_PAYMENT_DATE AS FIRST_PAYMENT_DATE, pe.FIRST_PAYMENT_DATE AS ADMIN_FIRST_PAYMENT_DATE, pe.test_users_email AS ADMIN_EMAIL, s.utm_source, s.utm_medium, s.utm_campaign, s.sf_exec, s.bounced_email,
s.vat_number, pe.company AS ADMIN_COMPANY
FROM test_users AS s
LEFT JOIN test_users_paid_for AS p ON email_users_email = s.test_users_email
LEFT JOIN test_users AS pe ON p.test_users_admin_id = pe.test_users_id
WHERE s.test_users_id = $userId
""".as(simple.single)
}
}