Параметр Scala [java.util.Date] не может быть преобразован в параметр [java.sql.Date]

У меня есть форма Play, которая выглядит так:

val form = Form( tuple( 
        /* 5 more fields */ 
        "dueDate" -> optional(date) 
)  )

Я пытаюсь вставить "dueDate" в объект в Slick.

newAuditForm.bindFromRequest.fold(
    errors => BadRequest(views.html.error(form)),
    success => {
        Database.forDataSource(DB.getDataSource()) withSession {
            Things.forInsert.insert Thing(
                (success._6).asInstanceOf[Option[java.sql.Date]] 
            )
        }
    }
)

где Slick работает только с java.sql.Date, а Play работает только с java.util.Date (?) в объекте Form.

Использование asInstanceOf возвращает:

     ClassCastException: java.util.Date cannot be cast to java.sql.Date

У меня должен быть способ написать правило для этого приведения, чтобы было возможно ... нужно ли мне писать новое правило сопоставления с образцом?


person Meredith    schedule 21.06.2013    source источник


Ответы (2)


Вы не можете преобразовать java.util.Date в java.sql.Date, потому что java.sql.Date является подклассом. Что вы можете сделать, так это создать новый экземпляр java.sql.Date:

val x = new java.util.Date()
val y = new java.sql.Date(x.getTime())

Вы можете определить неявное преобразование, если считаете его полезным:

implicit def date2sqlDate(d: java.util.Date) = new java.sql.Date(d.getTime())

Однако это не будет преобразовано внутри параметра (также не будет работать приведение, потому что это не приведение, а преобразование).

Вы также можете:

val x: Option[java.util.Date]
x.map(_: java.sql.Date) // using implicit conversion

Или просто напишите это явно:

x.map(d => new java.sql.Date(d.getTime()))

Если преобразование требуется очень часто, можно подумать о написании неявного преобразования из Option[java.util.Date] в Option[java.sql.Date].

person gzm0    schedule 21.06.2013
comment
Я не думаю, что стоит вводить неявное преобразование, если вы уже делаете явную карту с присвоением типа. - person om-nom-nom; 21.06.2013
comment
Спасибо за быстрый ответ. Я ценю, как вы потратили много времени, чтобы объяснить, что происходит. Правильно ли я понимаю, что явное преобразование - это скорее одноразовая вещь, а неявные преобразования эквивалентны написанию нового правила приведения типов? - person Meredith; 21.06.2013
comment
@MeredithLeu Добро пожаловать. Неявные преобразования - это специальные функции, используемые для преобразования, а не преобразования типов: если у вас есть значение x: A и вам нужно B, и у вас есть одна неявная функция f: A => B в области видимости, компилятор заменит x на f(x). Таким образом, на уровне байт-кода они представляют собой не что иное, как вызовы функций. Явное преобразование - это запись того же самого вызова функции. См. http://stackoverflow.com/questions/2861501/can-someone-explain-me-implicit-conversions-in-scala - person gzm0; 21.06.2013
comment
@ om-nom-nom Да, согласен. Я добавил это больше, чтобы показать общий механизм (и избежать путаницы с коробочным типом). Если преобразование требуется и в другом месте, оно может быть полезно. - person gzm0; 22.06.2013

Попробуйте сопоставить Option[java.util.Date] с Option[java.sql.Date] следующим образом:

(success._6).map(d => new java.sql.Date(d.getTime))

Еще один совет: вы можете фактически сопоставить это с java.sql.Timestamp, чтобы не терять точность времени при записи его в БД, как я полагаю, будет в случае с java.sql.Date. Итак, код будет:

(success._6).map(d => new java.sql.Timestamp(d.getTime))
person cmbaxter    schedule 21.06.2013
comment
Спасибо! Мне известно об использовании java.sql.Timestamp вместо Date. Я использую Option [Timestamp] где-нибудь в моей схеме, но для этого конкретного объекта детальность дня подойдет ^. ^ - person Meredith; 21.06.2013