Привет, У меня возникла проблема, когда я получаю UnexpectedNullableFound. Колон может вернуть нулевое значение, но у меня есть сопоставление (как показано ниже) в качестве опции, поэтому не должно вызывать проблемы. Это работает для других полей, которые я беру из этой таблицы. Если я удалю «pe.company AS admin_company» и связанные с ним сопоставления из кода, у меня нет никаких проблем.UnexpectedNullableFound on left join
Если 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)
}
}
В вашей проекции ('' '' '' '' '' '' '' '' '' '' '' '' колонны '' ''. Используйте только псевдоним в этом случае. P.S: 'getAlias' устарел. – cchantep
@cchantep Мы работаем на Anorm 2.4.0 в минуту, есть проблема с getAliased in 2.5, препятствующая нам обновляться. Мы ждем выхода 2.6 для обновления, так что застряли, используя getAlased прямо сейчас. Знаете ли вы, когда мы увидим 2.6? – smur89
'getAliased' больше не должен использоваться – cchantep