2017-10-25 16 views
0

最初に、私はまだSlickには新しく、ほとんどは学習していて、このような奇妙なケースを発見するたびに言及しなければなりません。Slick:ClassCastException:scala.Someはjava.lang.Stringにキャストすることはできません

は、私は次のようにケースクラスの住所はスリックテーブルに対して定義があります。

package model 

import driver.PGDriver.api._ 
import format.DateTimeFormat._ 
import org.joda.time.DateTime 
import play.api.libs.json._ 
import slick.lifted.Tag 

case class Address(id: Option[Int] = None, 
        countryId: Option[Int] = None, 
        continentId: Option[Int] = None, 
        stateId: Option[Int] = None, 
        address1: String, 
        address2: Option[String], 
        city: String, 
        zip: String, 
        createdAt: DateTime = DateTime.now, 
        updatedAt: DateTime = DateTime.now, 
        deletedAt: Option[DateTime] = None, 
        createdBy: Option[String] = None, 
        updatedBy: Option[String] = None) 

object Addresses { 

    val addresses = TableQuery[Addresses] 

    implicit lazy val addressFormat: Format[Address] = Json.format[Address] 

    Json.toJson[DateTime](DateTime.now) 

} 

class Addresses(tag: Tag) extends Table[Address](tag, "address") { 

    def id = column[Int]("id", O.PrimaryKey, O.AutoInc) 

    def countryId = column[Option[Int]]("country_id") 
    def continentId = column[Option[Int]]("continent_id") 
    def stateId = column[Option[Int]]("state_id") 

    def address1 = column[String]("address1", O.SqlType("character varying(255)")) 
    def address2 = column[Option[String]]("address1", O.SqlType("character varying(255)")) 
    def city = column[String]("city", O.SqlType("character varying(255)")) 
    def zip = column[String]("zip", O.SqlType("character varying(30)")) 

    def createdAt = column[DateTime]("createdat") 
    def updatedAt = column[DateTime]("updatedat") 
    def deletedAt = column[Option[DateTime]]("deletedat") 

    def createdBy = column[Option[String]]("createdby", O.SqlType("character varying(255)")) 
    def updatedBy = column[Option[String]]("updatedby", O.SqlType("character varying(255)")) 

    override def * = 
    (
     id.?, 
     countryId, 
     continentId, 
     stateId, 
     address1, 
     address2, 
     city, 
     zip, 
     createdAt, 
     updatedAt, 
     deletedAt, 
     createdBy, 
     updatedBy 
    ) <> (Address.tupled, Address.unapply) 

    def addressStateIdIdx = index("address_state_id_idx", stateId) 
    def state = 
    foreignKey("address_state_id_fkey", stateId, GeoAreas.areas)(
     _.id.?, 
     onUpdate = ForeignKeyAction.Cascade, 
     onDelete = ForeignKeyAction.Restrict 
    ) 

    def addressCountryIdIdx = index("address_country_id_idx", countryId) 
    def country = 
    foreignKey("address_country_id_fkey", countryId, GeoAreas.areas)(
     _.id.?, 
     onUpdate = ForeignKeyAction.Cascade, 
     onDelete = ForeignKeyAction.Restrict 
    ) 

    def addressContinentIdIdx = index("address_continent_id_idx", continentId) 
    def continent = 
    foreignKey("address_continent_id_fkey", continentId, GeoAreas.areas)(
     _.id.?, 
     onUpdate = ForeignKeyAction.Cascade, 
     onDelete = ForeignKeyAction.Restrict 
    ) 

} 

これが唯一の理由は、私が取得しています。このクラスでは、何らかの理由で、スリックによる作品と私の唯一のクラスではありませんが、 joinを使用してクエリを作成しようとしたときの例外です。これと同じように:

def search(searchCriteria: SearchCriteria, 
      readyOnly: Boolean, 
      drop: Long = 0, 
      take: Long = 100): Future[Seq[(School, Option[Address])]] = { 
    val q = for { 
     (school, address) <- Schools.schools joinLeft Addresses.addresses on (_.addressId === _.id) 
     if List(
     Some(school.deletedAt.isEmpty), 
     searchCriteria.school.name.map(n => school.name.toLowerCase like s"%${n.toLowerCase}%"), 
     searchCriteria.school.ready.map(r => school.ready === r) 
    ).collect({ case Some(criteria) => criteria }).reduceLeftOption(_ && _).getOrElse(true: Rep[Boolean]) 
    } yield (school, address) 

    db.run(q.drop(drop).take(take).result) 
    } 

私は取得しています例外がある:この特定の時点で play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[ClassCastException: scala.Some cannot be cast to java.lang.String]]

enter image description here

、私も問題を探して起動するには若干のアイデアを持っていません。 このクラスは他のクラスと非常によく似ています。他のすべては正常に動作します。 すべてが問題なくコンパイルされます。 例外は実行時にのみスローされます。

私には何が欠けていますか? おかげで、私は問題を発見したかもしれない

UPDATE

は、しかし、私はそれを修正するかどうかはわからないし、なぜそれが起こっています。 実行なっている実際のクエリはこれです:選択の一環として、いくつかの奇妙なcaseあり

SELECT 
    x2."id", 
    x2."address_id", 
    x2."name", 
    x2."about", 
    x2."number_of_students", 
    x2."website_url", 
    x2."media_id", 
    x2."slug", 
    x2."short_description", 
    x2."ready", 
    x2."classrooms", 
    x2."year_established", 
    x2."display_copyright", 
    x2."createdat", 
    x2."updatedat", 
    x2."deletedat", 
    x2."createdby", 
    x2."updatedby", 
    x2."dli_number", 
    (CASE WHEN (x3."id" IS NULL) 
    THEN NULL 
    ELSE 1 END), 
    x3."id", 
    x3."country_id", 
    x3."continent_id", 
    x3."state_id", 
    x3."address1", 
    x3."address1", 
    x3."city", 
    x3."zip", 
    x3."createdat", 
    x3."updatedat", 
    x3."deletedat", 
    x3."createdby", 
    x3."updatedby" 
FROM "school" x2 LEFT OUTER JOIN "address" x3 ON x2."address_id" = x3."id" 
WHERE ((x2."deletedat" IS NULL) AND (lower(x2."name") LIKE '%a%')) AND (x2."ready" = TRUE) 
LIMIT 100 
OFFSET 0 

。それはなぜそこにあるのですか?私は何を間違えているのですか?

UPDATE#2

一方から、クエリーの行を読み込み、正確にどのように滑らかな知らない、私はこのcase文は元の問題を引き起こす可能性があるかどうかわからないです。

しかし、私はまだ立ち往生しています。

UPDATE#3

だから、私はそうのように、アドレステーブルだけが含まれている可能性が最も簡単なクエリを試してみました:

def all(): Future[Seq[Address]] = db.run(Addresses.addresses.filter(_.deletedAt.isEmpty).result) 

そして、私はまだ同じ例外を取得しています。ここで

アップデート#4

は、実際のアドレステーブルです:

create table address 
(
    id bigserial not nullconstraint address_pkey primary key, 
    country_id bigint constraint address_country_id_fkey references geo_area on update cascade on delete restrict, 
    continent_id bigint constraint address_continent_id_fkey references geo_area on update cascade on delete restrict, 
    state_id bigint constraint address_state_id_idx references geo_area on update cascade on delete restrict, 
    address1 varchar(255) not null, 
    address2 varchar(255), 
    city varchar(255) not null, 
    zip varchar(30) not null, 
    deletedat timestamp with time zone, 
    createdat timestamp with time zone not null, 
    updatedat timestamp with time zone not null, 
    createdby varchar(255), 
    updatedby varchar(255) 
); 

create index address_country_id_idx on address (country_id); 

create index address_continent_id_idx on address (continent_id); 

create index address_state_id_idx on address (state_id); 
+1

これは、実行時に起こっている場合は、私は必ずそれが何と一致することを確認するために、データベースのスキーマを再確認でしょうあなたのテーブルの定義でSlickに言っています – Tyler

+0

私は何かを逃していない限り、それはかなり標準です。特別なものはありません。私はそれを投稿に追加しました。 –

答えて

1

私はそれは本当に愚かなものであるという感覚を持っていた、と私は正しかったです。 @Tylerは、正しい方向に私を指してくれてありがとうは 問題はここにあった:address2が定義されている方法で

def address1 = column[String]("address1", O.SqlType("character varying(255)")) 
    def address2 = column[Option[String]]("address1", O.SqlType("character varying(255)")) 

ルック。これらの2つの列名は重複していました。そう明らかにそれをすると仮定した

def address1 = column[String]("address1", O.SqlType("character varying(255)")) 
    def address2 = column[Option[String]]("address2", O.SqlType("character varying(255)")) 

例外は、いつものように、無意味です:)

関連する問題