2017-05-04 6 views
3

Play for Scalaの本を読んでいるうちに、本で説明された何か奇妙なことが出てきました。これは関連するスニペットです:Squerylを使った永続ストレージでのScalaの不変性

奇妙なことが起こっています。あなたがオブジェクトを挿入するとき フィールドが フィールドをアップデートすると、 がSquerylがあなたのオブジェクトのおそらく不変のidを更新することを発見したときに不安定な クラス(バニラケースクラスである)を使用していると心配するかもしれません。 Product(13, 5010255079763, "plastic coated blue", "standard paperclip, coated with blue plastic"):それは、あなたが 次のコードを実行した場合

val myImmutableObject = Product(0, 5010255079763, 
    "plastic coated blue", "standard paperclip, coated with blue plastic") 
Database.productsTable.insert(myImmutableObject) 
println(myImmutableObject) 

出力が突然のようなものになることを意味します。あなたのモデルクラスのインスタンスが決して変更されないとコードの残りの部分が期待している場合、これは悪い状況につながる可能性があります。 は、原料のこの種から身を守るために、私たちは、あなたがこれに先ほどお見せした挿入方法を変更 お勧めします。

def insert(product: Product): Product = inTransaction { 
    val defensiveCopy = product.copy 
    productsTable.insert(defensiveCopy) 
} 

私の質問は、製品のクラスは、次のように定義されていることを考えると、次のとおりです。

import org.squeryl.KeyedEntity 

case class Product(
    id: Long, 
    ean: Long, 
    name: String, 
    description: String) extends KeyedEntity[Long] 

Databaseオブジェクトは次のように定義される:

import org.squeryl.Schema 
import org.squeryl.PrimitiveTypeMode._ 
object Database extends Schema { 
    val productsTable = table[Product]("products") 
    ... 

    on(productsTable) { p => declare { 
     p.id is(autoIncremented) 
    }} 
} 

valとして宣言されたケースクラスは、そのフィールドの1つを変更することができますか? Squerylはフィールドを変更するために何らかの反射を使用していますか、何とか間違った本ですか?

私は事例を検証するために例を実行することはできませんが、Squerylを使用した人はおそらく答えを出すことができますか?

+0

それはケースクラスそのものではなく、 'table'ジェネリックで' val'と宣言されています。このテーブルに格納されているオブジェクトにアクセスするルールを指定します(実際はケースクラスとして表されます)。 – Ashalynd

+0

@ piet.t Lolはいそうです。私はそのようには考えなかった – smac89

答えて

0

あなたは自分のためtableメソッドの定義を確認することができます。

https://github.com/squeryl/squeryl/blob/master/src/main/scala/org/squeryl/Schema.scala#L345

それは、与えられたケースクラスにバインドされた表オブジェクトをインスタンス化するためにリフレクションを使用し、一般的な機能です。関数はスカラのファーストクラスの市民であるため、他のものと同じようにvalに割り当てることができます。

最後のフラグメントは、非同期関数でもあり、与えられた引数をそのために定義された変更にマップします。

関連する問題