2013-06-21 75 views
1

我有一个游戏的形式,看起来像这样:斯卡拉选项[java.util.Date]不能被转换为选项[java.sql.Date]

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]] 
      ) 
     } 
    } 
) 

油滑的地方只有java.sql.Date交易,并与java.util.Date只玩交易(?)在Form对象。

使用asInstanceOf回报:

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

还有的必须是一个办法,我写了规则这个转换成为可能...... 我需要写一个new pattern matching rule

回答

5

由于java.sql.Date是子类,所以不能将java.util.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 

或者只写它明确:

​​

如果需要转换非常频繁,你可能会考虑写一个隐式转换从Option[java.util.Date]Option[java.sql.Date]

+2

我不认为这是值得引入隐式转换,如果你已经做类型归属显式映射。 –

+0

感谢您的快速回复。我很感激你如何去解释发生了什么。 我的理解是显式转换更多是一次性的事情,而隐式转换相当于编写新的类型转换规则吗? – Meredith

+1

@MeredithLeu欢迎。隐式转换是用于转换的特殊函数,而不是类型转换:如果您有一个值'x:A',并且您需要一个'B'并且您有一个隐式函数'f:A => B',编译器将会用'f(x)'替换'x'。所以在字节码级别上,它们只不过是函数调用。显式转换正在编写完全相同的函数调用。请参阅:http:// stackoverflow。com/questions/2861501/can-someone-explain-me-implicit-conversions-in-scala – gzm0

4

尝试映射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)) 
+0

谢谢!我知道使用java.sql.Timestamp而不是Date。我在我的模式中的其他地方使用Option [Timestamp],但对于这个特定的对象,一天的粒度是很好的^。^ – Meredith