Package st.orm

Interface Ref<T extends Data>

Type Parameters:
T - record type.

public interface Ref<T extends Data>
Ref records are used to represent reference to records, allowing them to be fetched from the database. This can be used to defer the fetching of records until they are actually needed. Ref records are used to represent entities, projections and regular records.

Ref records are generally used for foreign key references in entities and projections, preventing deep object graphs. Alternatively, ref records can be used outside the scope entities and projections to simply act as a factory pattern for fetching records on demand.

Ref records are effectively immutable and can be used as keys in maps and sets. Equality is based on the primary key of the record and the actual record instance will be fetched at most once.

Since:
1.3
  • Method Summary

    Modifier and Type
    Method
    Description
    static <ID, E extends Entity<ID>>
    ID
    entityId(Ref<E> ref)
    Extracts the primary key from the given entity ref returning a type-safe id.
    default T
    Fetches the record if it has not been fetched yet.
    @Nullable T
    Fetches the record if it has not been fetched yet.
    @Nullable T
    Returns the record if it has already been fetched, without triggering a database call.
    default T
    Returns the record that is already loaded, without querying the database.
    id()
    Returns the primary key of the record.
    boolean
    Returns whether this ref is attached to a database context and capable of fetching the record on demand.
    default boolean
    Returns whether the record has already been fetched and is available in memory.
    static <E extends Entity<?>>
    Ref<E>
    of(E entity)
    Creates a fully loaded ref instance that wraps the given entity.
    static <T extends Data, ID>
    Ref<T>
    of(Class<T> type, ID pk)
    Creates a detached ref instance for the given type and primary key.
    static <P extends Projection<ID>, ID>
    Ref<P>
    of(P projection, ID id)
    Creates a fully loaded ref instance that wraps the given projection along with its row identity.
    static <ID, P extends Projection<ID>>
    ID
    projectionId(Ref<P> ref)
    Extracts the primary key from the given projection ref returning a type-safe id.
    The type of the record.
    Returns a detached ref with the same identity but without data.
  • Method Details

    • type

      Class<T> type()
      The type of the record.
      Returns:
      the type of the record.
    • of

      static <T extends Data, ID> Ref<T> of(Class<T> type, ID pk)
      Creates a detached ref instance for the given type and primary key.

      The returned ref is not connected to a database context. Calling fetch() or fetchOrNull() on a detached ref will return null since there is no database connection available to retrieve the record.

      Type Parameters:
      T - the type of the record, which must extend Data.
      ID - the type of the primary key.
      Parameters:
      type - the class of the record.
      pk - the primary key of the record.
      Returns:
      a detached ref instance for the given type and primary key.
    • of

      static <E extends Entity<?>> Ref<E> of(E entity)
      Creates a fully loaded ref instance that wraps the given entity.

      The entity does not need to be persisted yet: a ref wrapping an unsaved entity can act as a graph edge for dependency-aware write sets (see WriteSet), which insert the wrapped instance first and bind the generated key. Outside a write set, using an unsaved wrapped ref as a foreign key value fails fast at persist time. Note that ref equality is based on type and the row identity of the id (an entity-typed id counts by its primary key rather than by structural equality), so refs wrapping distinct unsaved entities compare equal until the entities are persisted.

      Type Parameters:
      E - the type of the entity, which must extend Record and implement Entity.
      Parameters:
      entity - the fully loaded entity to wrap in a ref.
      Returns:
      a fully loaded ref instance for the provided entity.
    • of

      static <P extends Projection<ID>, ID> Ref<P> of(P projection, ID id)
      Creates a fully loaded ref instance that wraps the given projection along with its row identity.

      The id is a parameter because Projection deliberately declares no id accessor: a projection's row identity is not in general derivable from its components. It may differ in type from the primary key component (a foreign key typed key is identified by the referenced table's key rather than the component value), or it may not be among the mapped columns at all.

      Type Parameters:
      P - the type of the projection.
      ID - the row identity type of the projection.
      Parameters:
      projection - the fully loaded projection to wrap in a ref.
      id - the row identity of the projection.
      Returns:
      a fully loaded ref instance for the provided projection.
    • entityId

      static <ID, E extends Entity<ID>> ID entityId(Ref<E> ref)
      Extracts the primary key from the given entity ref returning a type-safe id.
      Type Parameters:
      ID - the id type.
      E - the entity type.
      Parameters:
      ref - ref to extract the primary key from.
      Returns:
      the primary key of the specified ref.
    • projectionId

      static <ID, P extends Projection<ID>> ID projectionId(Ref<P> ref)
      Extracts the primary key from the given projection ref returning a type-safe id.
      Type Parameters:
      ID - the id type.
      P - the projection type.
      Parameters:
      ref - ref to extract the primary key from.
      Returns:
      the primary key of the specified ref.
    • id

      Object id()
      Returns the primary key of the record.

      This method is provided for convenience. If the type of the id is known, you can cast it to the appropriate type.

      Returns:
      the primary key as an Object.
    • getOrNull

      @Nullable T getOrNull()
      Returns the record if it has already been fetched, without triggering a database call.
      Returns:
      the record if already loaded, or null if not yet fetched.
      Since:
      1.7
    • getOrThrow

      default T getOrThrow()
      Returns the record that is already loaded, without querying the database.

      This is the counterpart of fetch() for a reference the query was asked to resolve. Where fetch() silently queries when the reference turns out not to be loaded, this method fails, so a query that does not resolve the reference is reported where the assumption was made rather than paid for one row at a time:

      
       List<User> users = orm.entity(User.class)
           .select()
           .fetch(User_.city)
           .getResultList();
      
       City city = users.getFirst().city().getOrThrow();   // no query; throws if the plan did not cover it
       

      Use fetch() when the reference is meant to be resolved on demand, and this method when the query is meant to have resolved it already. The record can be loaded without ever having been fetched, by of(Entity) for instance, and this method reads it either way; isLoaded() reports the same state.

      Returns:
      the record that is loaded.
      Throws:
      PersistenceException - if the record is not loaded.
      Since:
      1.13
    • fetch

      default T fetch()
      Fetches the record if it has not been fetched yet. The record will be fetched at most once.

      Within a transaction, this method may return the same instance as other retrieval operations for the same primary key without querying the database, depending on the transaction isolation level.

      Returns:
      the fetched record.
      Throws:
      PersistenceException - if the record is not available and the Ref is not attached.
    • fetchOrNull

      @Nullable T fetchOrNull()
      Fetches the record if it has not been fetched yet. Returns null if the record is not available and the Ref is not attached.

      Within a transaction, this method may return the same instance as other retrieval operations for the same primary key without querying the database, depending on the transaction isolation level.

      Returns:
      the fetched record, or null if the record is not available and the Ref is not attached.
      Since:
      1.7
    • isFetchable

      boolean isFetchable()
      Returns whether this ref is attached to a database context and capable of fetching the record on demand.

      A fetchable ref has access to a database connection and can attempt to retrieve the record when fetch() or fetchOrNull() is called. A non-fetchable (detached) ref can only return data that was already loaded at the time of its creation.

      Note that this method indicates the capability to fetch, not a guarantee of success. A fetchable ref may still fail to retrieve a record if it has been deleted from the database or if the connection encounters an error.

      Returns:
      true if this ref can attempt to fetch from the database, false if it is detached.
      Since:
      1.7
    • isLoaded

      default boolean isLoaded()
      Returns whether the record has already been fetched and is available in memory.

      This method does not trigger a database call. It simply checks if the record is currently cached.

      Returns:
      true if the record is loaded and available via getOrNull(), false otherwise.
      Since:
      1.7
    • unload

      Ref<T> unload()
      Returns a detached ref with the same identity but without data.

      The returned ref is not attached to a database context. Calling fetch() on the returned ref will fail since there is no database connection to recover the data.

      For refs that are already detached and unloaded, this method may return the same instance.

      Returns:
      a detached ref with the same type and primary key but without cached data.