longevity

A Persistence Framework for Scala and NoSQL

View project on GitHub

key values

Key values are used to uniquely identify a persistent object. They can be embedded in persistents in two different ways. The first way to embed a key value is as a unique identifier for the persistent in question. For example, we may want to stipulate that every User has a unique Username. We can model this in longevity like so:

import longevity.model.annotations.keyVal
import longevity.model.annotations.persistent

@keyVal[User]
case class Username(username: String)

@persistent(keySet = Set(key(props.username)))
case class User(
  username: Username,
  firstName: String,
  lastName: String)

The key(props.username) in the @persistent annotation defines the key for our key value type Username. We will go into the details of keys in a later section, but we include them here so that the examples are correct.

The second way we can embed a KeyVal in a persistent object is as a reference to some other persistent object. As an example, let’s suppose that the users in our domain have an optional sponsor. We can specify the sponsor by providing the sponsor’s username, like so:

import longevity.model.annotations.keyVal
import longevity.model.annotations.persistent

@keyVal[User]
case class Username(username: String)

@persistent(keySet = Set(key(props.username)))
case class User(
  username: Username,
  firstName: String,
  lastName: String,
  sponsor: Option[Username])

This sponsor field represents a relationship between two persistent objects. In UML, we call this kind of relationship an aggregation. With aggregations, the life cycles of the entities in question are independent.

As we can see in the previous example, KeyVals can appear inside collections. They can also appear within components. KeyVals can have multiple fields in them, and they can even embed other KeyVals. But they cannot contain any collections or polymorphic objects.

We can always look up a persistent object by KeyVal using repository method Repo.retrieve, as we will discuss in a later section.

The non-annotation equivalent for the key value looks like this:

import longevity.model.KeyVal

case class Username(username: String) extends KeyVal[User]

Clearly, the keyVal annotation is not providing any interesting functionality, or reducing any boilerplate. We include this annotation for consistency, so that it is possible to construct a domain model only using annotations.

prev: components
up: the domain model
next: limitations on persistents, components, and key values