Package

model

persistence

Permalink

package persistence

Using raw types such as Long, java.util.UUID, and Option[Long] for database ids invites errors. Scala developers should instead use the Id and HasId wrapper types provided by this project because of the type safety they provide over raw types. Id and HasId are database-agnostic. Both auto-increment Ids and Ids whose value is defined before persisting them are supported.

Id

Id can wrap Long, UUID and String values, and any of them can be optional. The supported flavors of Id are:

Id is a Scala value object, which means there is little or no runtime cost for using it as compared to the value that it wraps. In other words, there is no penalty for boxing and unboxing.

Convenience Types

For convenience, the following types are defined in Types:

Id.empty

Ids define a special value, called empty. Each Id flavor has a unique value for empty. FYI, the values for empty are:

Depending on the context, you might need to provide type ascription when using Id.empty. For example, IdUuid.empty or IdOptionLong.empty.

Id.toOption

You can use the Id.toOption method to convert from an IdLong or IdUuid to IdOptionLong or IdOptionUuid.

scala> import model.persistence._
import model.persistence._

scala> Id(Option(123L)).toOption
res2: model.persistence.Id[_ >: Option[Long] with Option[Option[Long]]] = 123

Be sure to cast the result to the desired Id subtype, otherwise you'll get a weird unhelpful type:

scala> Id(Option(123L)).toOption.asInstanceOf[IdLong]
res3: model.persistence.Id[Long] = 123

scala> import java.util.UUID
import java.util.UUID

scala> Id(Option(UUID.randomUUID)).toOption.asInstanceOf[IdUUID]
res3: model.persistence.Id[java.util.UUID] = b4570530-14d0-47d6-9d8b-af3b58ed075a

HasId

Each case class that uses Id to represent the persisted record id in the database must extend HasId. HasId is a parametric type with two type parameters:

For example, you can make MyCaseClass extend HasId by writing something like this for the extended type:

Usage Examples

Here are examples of using Id and HasId:

Simple Example
/** A person can have at most one Dog.
  * Because their Id is based on `OptionUuid`, those `Id`s do not always have `Some` value */
case class Person(
   age: Int,
   name: String,
   dogId: Id[OptionLong],
   override val id: Id[UUID] = Id(UUID.randomUUID) // Id type (UUID) matches the HasId type (also UUID)
 ) extends HasId[Person, UUID]

/** Dogs are territorial. They ensure that no other Dogs are allowed near their FavoriteTrees.
  * Because the Ids for Dog and FavoriteTree are based on Option[Long] and not UUID,
  * those Ids might have value None until they are persisted */
case class Dog(
  species: String,
  color: String,
  override val id: Id[OptionLong] = Id.empty
) extends HasId[Dog, OptionLong]
HasId Sub-Subclasses

Subclasses of HasId subclasses should be parametric. In the following example, Rateable is an abstract class that subclasses HasId. Notice that Rateable is parametric in T, and HasId's first type parameter is also T:

abstract class Rateable[T](override val id: IdOptionLong) extends HasId[T, OptionLong]

The following two Rateable subclasses provide values for T that match the names of the derived classes:

case class Inquiry(
  title: String,
  body: String,
  userId: IdOptionLong,
  lectureId: IdOptionLong,
  override val id: IdOptionLong = Id.empty
) extends Rateable[Inquiry](id)

case class Recording(
  ohSlotId: IdOptionLong,
  transcript: String,
  active: Boolean = false,
  override val id: IdOptionLong = Id.empty
) extends Rateable[Recording](id)
Source
package.scala
Linear Supertypes
AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. persistence
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Type Members

  1. class Copier extends AnyRef

    Permalink

    Utility class for providing copying of a designated case class with minimal overhead.

    Utility class for providing copying of a designated case class with minimal overhead. ONLY WORKS WITH TOP-LEVEL CASE CLASSES

  2. trait HasId[T, A] extends IdImplicitLike

    Permalink
  3. case class Id[T](value: T)(implicit evidence$6: IdType[T]) extends HasValue[T] with Product with Serializable

    Permalink
  4. sealed class IdConverter[From, To] extends AnyRef

    Permalink
    Attributes
    protected
  5. trait IdImplicitLike extends AnyRef

    Permalink

    To use, either import IdImplicits._ or mix in IdImplicitLike

  6. sealed class IdType[+T] extends AnyRef

    Permalink
    Attributes
    protected

Value Members

  1. object Copier

    Permalink

    Modified from StackOverflow

  2. object Id extends IdImplicitLike with Serializable

    Permalink
  3. object IdConverter

    Permalink
    Attributes
    protected
  4. object IdImplicits extends IdImplicitLike

    Permalink
  5. object IdType

    Permalink
    Attributes
    protected
  6. object Types

    Permalink

Inherited from AnyRef

Inherited from Any

Ungrouped