2017-05-04 5 views
3

So wie ich das Play for Scala Buch lese, stieß ich auf etwas Seltsames, das in dem Buch erklärt wurde. Dies ist das relevante Codefragment:Scala Unveränderlichkeit im persistenten Speicher mit Squeryl

Es passiert jedoch etwas Seltsames. Wenn Sie unveränderliche -Klassen verwenden - welche Vanilla-Fallklassen sind -, können Sie sich sorgen, wenn Sie entdecken, dass Squeryl die vermeintlich unveränderliche ID Ihres Objekts aktualisiert, wenn Sie das Objekt einfügen. Das bedeutet, dass, wenn Sie den folgenden Code ausführen,

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

der Ausgang unerwartet etwas sein wie: Product(13, 5010255079763, "plastic coated blue", "standard paperclip, coated with blue plastic"). Dies kann zu schlimmen Situationen führen, wenn der Rest Ihres Codes erwartet, dass sich eine Instanz einer Ihrer Modellklassen nie ändert. Um sich von dieser Art von Sachen zu schützen, empfehlen wir Ihnen die Einsatzmethoden ändern zeigten wir Ihnen früher in diese:

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

Meine Frage ist, da die Produktklasse wie folgt definiert ist:

import org.squeryl.KeyedEntity 

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

Database Objekt ist wie folgt definiert:

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

Wie ist es dann möglich, dass eine Fallklasse, die als val deklariert ist, eines ihrer Felder ändern kann? Verwendet Squeryl eine Art von Reflexion, um das Feld zu verändern, oder ist das Buch irgendwie falsch?

Ich kann die Beispiele nicht ausführen, um zu überprüfen, was der Fall sein könnte, aber jemand, der Squeryl verwendet hat, kann vielleicht eine Antwort geben?

+0

Es ist nicht die Fall-Klasse selbst, es ist die 'table' generische, die als' val' deklariert wird. Sie gibt die Regeln für den Zugriff auf die in dieser Tabelle gespeicherten Objekte an (die tatsächlich als Fallklassen dargestellt werden). – Ashalynd

+0

@ piet.t Lol ja du hast Recht. Daran habe ich nicht gedacht – smac89

Antwort

0

Sie können die Definition von table Methode für sich selbst überprüfen:

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

Es ist eine generische Funktion, die Verwendung Reflexion tut, um das Table-Objekt instanziiert die gegebenen Fall Klasse gebunden. Funktionen sind erstklassige Bürger in Scala, so dass sie genau wie alles andere einem Val zugewiesen werden können.

Das letzte Fragment ist auch eine asynchrone Funktion, die ein gegebenes Argument einer dafür definierten Modifikation zuordnet.

Verwandte Themen