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
To use, either import IdImplicits._ or mix in IdImplicitLike
Modified from StackOverflow
Using raw types such as
Long,java.util.UUID, andOption[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.IdandHasIdare database-agnostic. Both auto-incrementIds andIds whose value is defined before persisting them are supported.Id
Idcan wrapLong,UUIDandStringvalues, and any of them can be optional. The supported flavors ofIdare:Id[Long]- maps to PostgresBIGINTorBIGSERIALId[UUID]- do not misuseId[String]Id[Option[Long]]- commonly used with autoincrement columnsId[Option[UUID]]Id[Option[String]]Idis 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:
OptionLong–Option[Long]OptionString–Option[String]OptionUuid–Option[UUID]IdLong–Id[Long]IdString–Id[String]IdUuid–Id[UUID]IdOptionLong–Id[Option[Long]IdOptionString–Id[Option[String]]IdOptionUuid–Id[Option[UUID]]Id.empty
Ids define a special value, calledempty. EachIdflavor has a unique value forempty. FYI, the values foremptyare:IdUuid.empty == new UUID(0, 0)IdLong.empty == 0LIdString.empty == ""IdOptionUuid.empty = NoneIdOptionLong.empty = NoneIdOptionString.empty = NoneDepending on the context, you might need to provide type ascription when using
Id.empty. For example,IdUuid.emptyorIdOptionLong.empty.Id.toOption
You can use the
Id.toOptionmethod to convert from anIdLongorIdUuidtoIdOptionLongorIdOptionUuid.Be sure to cast the result to the desired
Idsubtype, otherwise you'll get a weird unhelpful type:HasId
Each case class that uses
Idto represent the persisted record id in the database must extendHasId.HasIdis a parametric type with two type parameters:Idfor the case class.For example, you can make
MyCaseClassextendHasIdby writing something like this for the extended type:HasId[MyCaseClass, Long]HasId[MyCaseClass, UUID]HasId[MyCaseClass, String]HasId[MyCaseClass, OptionLong]– Most commonly used flavorHasId[MyCaseClass, OptionUuid]HasId[MyCaseClass, OptionString]Usage Examples
Here are examples of using
IdandHasId:Simple Example
HasId Sub-Subclasses
Subclasses of
HasIdsubclasses should be parametric. In the following example,Rateableis an abstract class that subclassesHasId. Notice thatRateableis parametric inT, andHasId's first type parameter is alsoT:The following two
Rateablesubclasses provide values forTthat match the names of the derived classes: