Class PersistenceContext


  • public class PersistenceContext
    extends Object
    This class holds persistence context information.

    All non-saved modified data is referenced here. At save time, the data is sent to the database by the Mapper. The database will at some time later be committed by the external transaction manager in effect.

    Internally a fragment can be in at most one of the "pristine" or "modified" map. After a save() all the fragments are pristine, and may be partially invalidated after commit by other local or clustered contexts that committed too.

    Depending on the table, the context may hold SimpleFragments, which represent one row, CollectionFragments, which represent several rows.

    This class is not thread-safe, it should be tied to a single session and the session itself should not be used concurrently.

    • Field Detail

      • log

        protected static final Log log
      • SEL_WARN_THRESHOLD_PROP

        public static final String SEL_WARN_THRESHOLD_PROP
        Property for threshold at which we warn that a Selection may be too big, with stack trace.
        Since:
        7.1
        See Also:
        Constant Field Values
      • model

        protected final Model model
      • disableReadVersionPermission

        protected final boolean disableReadVersionPermission
      • pristine

        protected final Map<RowId,​Fragment> pristine
        The pristine fragments. All held data is identical to what is present in the database and could be refetched if needed.

        This contains fragment that are Fragment.State.PRISTINE or Fragment.State.ABSENT, or in some cases Fragment.State.INVALIDATED_MODIFIED or Fragment.State.INVALIDATED_DELETED.

        Pristine fragments must be kept here when referenced by the application, because the application must get the same fragment object if asking for it twice, even in two successive transactions.

        This is memory-sensitive, a fragment can always be refetched if nobody uses it and the GC collects it. Use a weak reference for the values, we don't hold them longer than they need to be referenced, as the underlying mapper also has its own cache.

      • userChangeIds

        protected final Set<Serializable> userChangeIds
        Document ids modified as "user changes", which means that a change token should be checked.
        Since:
        9.2
      • registry

        protected final io.dropwizard.metrics5.MetricRegistry registry
        Cache statistics
        Since:
        5.7
      • cacheCount

        protected final io.dropwizard.metrics5.Counter cacheCount
      • cacheHitCount

        protected final io.dropwizard.metrics5.Counter cacheHitCount
      • bigSelWarnThreshold

        protected long bigSelWarnThreshold
        Threshold at which we warn that a Selection may be too big, with stack trace.
    • Method Detail

      • clearCaches

        protected int clearCaches()
      • clearLocalCaches

        protected int clearLocalCaches()
      • getCacheSize

        protected long getCacheSize()
      • getCacheMapperSize

        protected long getCacheMapperSize()
      • getCachePristineSize

        protected long getCachePristineSize()
      • getCacheSelectionSize

        protected long getCacheSelectionSize()
      • generateNewId

        protected Serializable generateNewId​(Serializable id)
        Generates a new id, or used a pre-generated one (import).
      • markUserChange

        protected void markUserChange​(Serializable id)
        Marks this document id as belonging to a user change.
        Since:
        9.2
      • getSaveBatch

        protected RowMapper.RowBatch getSaveBatch​(List<Fragment> fragmentsToClearDirty)
        Saves all the created, modified and deleted rows into a batch object, for later execution.

        Also updates the passed fragmentsToClearDirty list with dirty modified fragments, for later call of clearDirty (it's important to call it later and not now because for delta values we need the delta during batch write, and they are cleared by clearDirty).

      • updateChangeToken

        protected Map<String,​Serializable> updateChangeToken​(SimpleFragment hier)
        Updates a change token in the main fragment, and returns the condition to check.
      • findModifiedDocuments

        protected Set<Serializable> findModifiedDocuments()
        Finds the documents having been modified.

        A document is modified if any of its direct fragments (same id) is modified, or if any of its complex property fragments having it as an ancestor is created, modified or deleted.

        Created and deleted documents aren't considered modified.

        Returns:
        the set of modified documents
        Since:
        9.1
      • findDirtyDocuments

        protected void findDirtyDocuments​(Set<Serializable> dirtyStrings,
                                          Set<Serializable> dirtyBinaries)
        Finds the documents having dirty text or dirty binaries that have to be reindexed as fulltext.
        Parameters:
        dirtyStrings - set of ids, updated by this method
        dirtyBinaries - set of ids, updated by this method
      • markInvalidated

        protected void markInvalidated​(VCSInvalidations invalidations)
        Marks locally all the invalidations gathered by a Mapper operation (like a version restore).
      • setFragmentModified

        protected void setFragmentModified​(Fragment fragment)
      • setFragmentPristine

        protected void setFragmentPristine​(Fragment fragment)
      • sendInvalidationsToOthers

        public void sendInvalidationsToOthers()
        Post-transaction invalidations notification.

        Called post-transaction by session commit/rollback or transactionless save.

      • processReceivedInvalidations

        public void processReceivedInvalidations()
        Applies all invalidations accumulated.

        Called pre-transaction by start or transactionless save;

      • checkInvalidationsConflict

        public void checkInvalidationsConflict()
      • get

        protected Fragment get​(RowId rowId,
                               boolean allowAbsent)
        Gets a fragment.

        If it's not in the context, fetch it from the mapper. If it's not in the database, returns null or an absent fragment.

        Deleted fragments may be returned.

        Parameters:
        rowId - the fragment id
        allowAbsent - true to return an absent fragment as an object instead of null
        Returns:
        the fragment, or null if none is found and allowAbsent was false
      • getFromMapper

        protected Fragment getFromMapper​(RowId rowId,
                                         boolean allowAbsent,
                                         boolean cacheOnly)
        Gets a fragment from the context or the mapper cache or the underlying database.
        Parameters:
        rowId - the fragment id
        allowAbsent - true to return an absent fragment as an object instead of null
        cacheOnly - only check memory, not the database
        Returns:
        the fragment, or when allowAbsent is false, a null if not found
      • getFromMapper

        protected List<Fragment> getFromMapper​(Collection<RowId> rowIds,
                                               boolean allowAbsent,
                                               boolean cacheOnly)
        Gets a collection of fragments from the mapper. No order is kept between the inputs and outputs.

        Fragments not found are not returned if allowAbsent is false.

      • getMulti

        public List<Fragment> getMulti​(Collection<RowId> rowIds,
                                       boolean allowAbsent)
        Gets a list of fragments.

        If a fragment is not in the context, fetch it from the mapper. If it's not in the database, use an absent fragment or skip it.

        Deleted fragments are skipped.

        Parameters:
        rowIds - the row ids
        allowAbsent - true to return an absent fragment as an object instead of skipping it
        Returns:
        the fragments, in arbitrary order (no nulls)
      • getFragmentsFromFetchedRows

        protected List<Fragment> getFragmentsFromFetchedRows​(List<? extends RowId> rowIds,
                                                             boolean allowAbsent)
        Turns the given rows (just fetched from the mapper) into fragments and record them in the context.

        For each row, if the context already contains a fragment with the given id, it is returned instead of building a new one.

        Deleted fragments are skipped.

        If a simple RowId is passed, it means that an absent row was found by the mapper. An absent fragment will be returned, unless allowAbsent is false in which case it will be skipped.

        Parameters:
        rowIds - the list of rows or row ids
        allowAbsent - true to return an absent fragment as an object instead of null
        Returns:
        the list of fragments
      • getFragmentFromFetchedRow

        protected Fragment getFragmentFromFetchedRow​(RowId rowId,
                                                     boolean allowAbsent)
        Turns the given row (just fetched from the mapper) into a fragment and record it in the context.

        If the context already contains a fragment with the given id, it is returned instead of building a new one.

        If the fragment was deleted, null is returned.

        If a simple RowId is passed, it means that an absent row was found by the mapper. An absent fragment will be returned, unless allowAbsent is false in which case null will be returned.

        Parameters:
        rowId - the row or row id (may be null)
        allowAbsent - true to return an absent fragment as an object instead of null
        Returns:
        the fragment, or null if it was deleted
      • createHierarchyFragment

        public SimpleFragment createHierarchyFragment​(Row row)
      • createdProxyFragment

        public void createdProxyFragment​(SimpleFragment fragment)
      • removedProxyTarget

        public void removedProxyTarget​(SimpleFragment fragment)
      • addedProxyTarget

        public void addedProxyTarget​(SimpleFragment fragment)
      • removePropertyNode

        public void removePropertyNode​(SimpleFragment hierFragment)
        Removes a property node and its children.

        There's less work to do than when we have to remove a generic document node (less selections, and we can assume the depth is small so recurse).

      • getNodeAndDescendantsInfo

        public List<RowMapper.NodeInfo> getNodeAndDescendantsInfo​(SimpleFragment hierFragment)
        Gets descendants infos from a given root node. This includes information about the root node itself.
        Since:
        9.2
      • removeNode

        public void removeNode​(SimpleFragment hierFragment,
                               List<RowMapper.NodeInfo> nodeInfos)
        Removes a document node and its children.

        Assumes a full flush was done.

      • removeFragment

        public void removeFragment​(Fragment fragment,
                                   boolean primary)
        Deletes a fragment from the context. May generate a database DELETE if primary is true, otherwise consider that database removal will be a cascade-induced consequence of another DELETE.
      • recomputeVersionSeries

        public void recomputeVersionSeries​(Serializable versionSeriesId)
        Recomputes isLatest / isLatestMajor on all versions.
      • getVersionIds

        public List<Serializable> getVersionIds​(Serializable versionSeriesId)
        Gets the version ids for a version series, ordered by creation time.
      • getPath

        public String getPath​(SimpleFragment hierFragment)
        Gets the path by recursing up the hierarchy.
      • getPathOrMissingParentId

        public PersistenceContext.PathAndId getPathOrMissingParentId​(SimpleFragment hierFragment,
                                                                     boolean fetch)
        Gets the full path, or the closest parent id which we don't have in cache.

        If fetch is true, returns the full path.

        If fetch is false, does not touch the mapper, only the context, therefore may return a missing parent id instead of the path.

        Parameters:
        fetch - true if we can use the database, false if only caches should be used
      • getContainingDocument

        public Serializable getContainingDocument​(Serializable id)
        Finds the id of the enclosing non-complex-property node.
        Parameters:
        id - the id
        Returns:
        the id of the containing document, or null if there is no parent or the parent has been deleted.
      • isDeleted

        public boolean isDeleted​(Serializable id)
        Recursively checks if any of a fragment's parents has been deleted.
      • getNextPos

        public Long getNextPos​(Serializable nodeId,
                               boolean complexProp)
        Gets the next pos value for a new child in a folder.
        Parameters:
        nodeId - the folder node id
        complexProp - whether to deal with complex properties or regular children
        Returns:
        the next pos, or null if not orderable
      • orderBefore

        public void orderBefore​(Serializable parentId,
                                Serializable sourceId,
                                Serializable destId)
        Order a child before another.
        Parameters:
        parentId - the parent id
        sourceId - the node id to move
        destId - the node id before which to place the source node, if null then move the source to the end
      • checkNotUnder

        protected void checkNotUnder​(Serializable parentId,
                                     Serializable id,
                                     String op)
        Checks that we don't move/copy under ourselves.
      • checkFreeName

        protected void checkFreeName​(Serializable parentId,
                                     String name,
                                     boolean complexProp)
        Checks that a name is free. Cannot check concurrent sessions though.
      • move

        public void move​(Node source,
                         Serializable parentId,
                         String name)
        Move a child to a new parent with a new name.
        Parameters:
        source - the source
        parentId - the destination parent id
        name - the new name
      • copy

        public Serializable copy​(Node source,
                                 Serializable parentId,
                                 String name,
                                 Consumer<Serializable> afterRecordCopy)
        Copy a child to a new parent with a new name.
        Parameters:
        source - the source of the copy
        parentId - the destination parent id
        name - the new name
        afterRecordCopy - a consumer called on ids of nodes that were records before copy
        Returns:
        the id of the copy
      • checkIn

        public Serializable checkIn​(Node node,
                                    String label,
                                    String checkinComment)
        Checks in a node (creates a version).
        Parameters:
        node - the node to check in
        label - the version label
        checkinComment - the version description
        Returns:
        the created version id
      • checkOut

        public void checkOut​(Node node)
        Checks out a node.
        Parameters:
        node - the node to check out
      • restoreVersion

        public void restoreVersion​(Node node,
                                   Node version)
        Restores a node to a given version.

        The restored node is checked in.

        Parameters:
        node - the node
        version - the version to restore on this node