2014-11-29 12 views
7

Ho questi classi case:Definire la proiezione di mappa per classi case annidate

case class PolicyHolder(id : String, firstName : String, lastName : String) 
case class Policy(address : Future[Address], policyHolder : Future[PolicyHolder], created : RichDateTime, duration : RichDuration) 

poi ho uno schema chiazza di petrolio definito per la politica

class PolicyDAO(tag: Tag) extends Table[Policy](tag, "POLICIES") with DbConfig { 
    def address = column[String]("ADDRESS", O.PrimaryKey) 
    def policyHolder = foreignKey("POLICY_HOLDER_FK", address, TableQuery[PolicyHolderDAO])(_.id) 

    def created = column[RichDateTime]("CREATED") 
    def duration = column[String]("DURATION") 

    def * = (address, policyHolder, created, duration) <> (Policy.apply, Policy.unapply) 
} 

Qual è il modo migliore per me per definire questa proiezione corretta per mappare il campo policyHolder all'interno della mia classe di caso Policy dal valore di chiave esterna a un'istanza effettiva della classe di caso PolicyHolder.

risposta

3

La nostra soluzione a questo problema è posizionare l'id della chiave esterna nella classe case e quindi utilizzare un valore lazy val o def (quest'ultimo eventualmente supportato da una cache) per recuperare il record utilizzando la chiave. Questo presuppone che i tuoi PolicyHolder siano memorizzati in una tabella separata - se sono denormalizzati ma li vuoi considerare come classi di casi distinti, allora puoi avere il valore lazy val/def in Policy costruire una nuova classe di casi invece di recuperare il record utilizzando la chiave esterna.

class PolicyDAO(tag: Tag) extends Table[Policy](tag, "POLICIES") with DbConfig { 
    def address = column[String]("ADDRESS", O.PrimaryKey) 
    def policyHolderId = column[String]("POLICY_HOLDER_ID") 

    def created = column[RichDateTime]("CREATED") 
    def duration = column[String]("DURATION") 

    def * = (address, policyHolderId, created, duration) <> (Policy.apply, Policy.unapply) 
} 

case class Policy(address : Future[Address], policyHolderId : Future[String], created : RichDateTime, duration : RichDuration) { 
    lazy val policyHolder = policyHolderId.map(id => PolicyHolderDAO.get(id)) 
} 

Abbiamo usato anche un insieme comune di creare/aggiornare/cancellare i metodi per tenere conto della nidificazione, in modo che quando un Policy si impegna suo interno saranno anche impegnati PolicyHolder; abbiamo utilizzato una classe CommonDAO che ha esteso Table e aveva i prototipi per i metodi create/update/delete e quindi tutti i DAO estesi CommonDAO anziché Table e overrode create/update/delete in base alle esigenze.


Modifica: Per ridurre l'errori e ridurre la quantità di boilerplate abbiamo dovuto scrivere, abbiamo usato di Slick code generation tool - in questo modo le operazioni CRUD potrebbero essere generati automaticamente dallo schema

Problemi correlati