Class PersistenceContext
- java.lang.Object
-
- org.nuxeo.ecm.core.storage.sql.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
SimpleFragment
s, which represent one row,CollectionFragment
s, 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.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
PersistenceContext.PathAndId
-
Field Summary
Fields Modifier and Type Field Description protected long
bigSelWarnThreshold
Threshold at which we warn that a Selection may be too big, with stack trace.protected io.dropwizard.metrics5.Counter
cacheCount
protected io.dropwizard.metrics5.Counter
cacheHitCount
protected boolean
disableReadVersionPermission
protected SelectionContext
hierComplex
SelectionContext
hierNonComplex
protected static Log
log
protected RowMapper
mapper
protected Model
model
protected Map<RowId,Fragment>
modified
The fragments changed by the session.protected static SimpleFragment.FieldComparator
POS_COMPARATOR
protected Map<RowId,Fragment>
pristine
The pristine fragments.protected io.dropwizard.metrics5.MetricRegistry
registry
Cache statisticsstatic String
SEL_WARN_THRESHOLD_DEFAULT
static String
SEL_WARN_THRESHOLD_PROP
Property for threshold at which we warn that a Selection may be too big, with stack trace.protected SessionImpl
session
protected Set<Serializable>
userChangeIds
Document ids modified as "user changes", which means that a change token should be checked.protected static SimpleFragment.FieldComparator
VER_CREATED_COMPARATOR
protected BaseSession.VersionAclMode
versionAclMode
-
Constructor Summary
Constructors Constructor Description PersistenceContext(Model model, RowMapper mapper, SessionImpl session)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
addedProxyTarget(SimpleFragment fragment)
protected void
checkFreeName(Serializable parentId, String name, boolean complexProp)
Checks that a name is free.Serializable
checkIn(Node node, String label, String checkinComment)
Checks in a node (creates a version).void
checkInvalidationsConflict()
protected void
checkNotUnder(Serializable parentId, Serializable id, String op)
Checks that we don't move/copy under ourselves.void
checkOut(Node node)
Checks out a node.protected int
clearCaches()
protected int
clearLocalCaches()
Serializable
copy(Node source, Serializable parentId, String name, Consumer<Serializable> afterRecordCopy)
Copy a child to a new parent with a new name.void
createdProxyFragment(SimpleFragment fragment)
SimpleFragment
createHierarchyFragment(Row row)
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.protected Set<Serializable>
findModifiedDocuments()
Finds the documents having been modified.protected Serializable
generateNewId(Serializable id)
Generates a new id, or used a pre-generated one (import).protected Fragment
get(RowId rowId, boolean allowAbsent)
Gets a fragment.protected long
getCacheMapperSize()
protected long
getCachePristineSize()
protected long
getCacheSelectionSize()
protected long
getCacheSize()
SimpleFragment
getChildHierByName(Serializable parentId, String name, boolean complexProp)
List<SimpleFragment>
getChildren(Serializable parentId, String name, boolean complexProp)
Gets hier fragments for children.Serializable
getContainingDocument(Serializable id)
Finds the id of the enclosing non-complex-property node.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.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.protected List<Fragment>
getFromMapper(Collection<RowId> rowIds, boolean allowAbsent, boolean cacheOnly)
Gets a collection of fragments from the mapper.protected Fragment
getFromMapper(RowId rowId, boolean allowAbsent, boolean cacheOnly)
Gets a fragment from the context or the mapper cache or the underlying database.protected SimpleFragment
getHier(Serializable id, boolean allowAbsent)
protected Fragment
getIfPresent(RowId rowId)
Gets a fragment, if present in the context.List<Fragment>
getMulti(Collection<RowId> rowIds, boolean allowAbsent)
Gets a list of fragments.Long
getNextPos(Serializable nodeId, boolean complexProp)
Gets the next pos value for a new child in a folder.List<RowMapper.NodeInfo>
getNodeAndDescendantsInfo(SimpleFragment hierFragment)
Gets descendants infos from a given root node.String
getPath(SimpleFragment hierFragment)
Gets the path by recursing up the hierarchy.PersistenceContext.PathAndId
getPathOrMissingParentId(SimpleFragment hierFragment, boolean fetch)
Gets the full path, or the closest parent id which we don't have in cache.protected RowMapper.RowBatch
getSaveBatch(List<Fragment> fragmentsToClearDirty)
Saves all the created, modified and deleted rows into a batch object, for later execution.List<Serializable>
getSeriesProxyIds(Serializable versionSeriesId)
Set<Serializable>
getTargetProxies(Set<Serializable> ids)
List<Serializable>
getTargetProxyIds(Serializable targetId)
List<Serializable>
getVersionIds(Serializable versionSeriesId)
Gets the version ids for a version series, ordered by creation time.boolean
isDeleted(Serializable id)
Recursively checks if any of a fragment's parents has been deleted.protected boolean
isIdNew(Serializable id)
protected void
markInvalidated(VCSInvalidations invalidations)
Marks locally all the invalidations gathered by aMapper
operation (like a version restore).protected void
markUserChange(Serializable id)
Marks this document id as belonging to a user change.void
move(Node source, Serializable parentId, String name)
Move a child to a new parent with a new name.void
orderBefore(Serializable parentId, Serializable sourceId, Serializable destId)
Order a child before another.void
processReceivedInvalidations()
Applies all invalidations accumulated.void
recomputeVersionSeries(Serializable versionSeriesId)
Recomputes isLatest / isLatestMajor on all versions.void
removedProxyTarget(SimpleFragment fragment)
void
removeFragment(Fragment fragment, boolean primary)
Deletes a fragment from the context.void
removeNode(SimpleFragment hierFragment, List<RowMapper.NodeInfo> nodeInfos)
Removes a document node and its children.void
removePropertyNode(SimpleFragment hierFragment)
Removes a property node and its children.void
restoreVersion(Node node, Node version)
Restores a node to a given version.void
sendInvalidationsToOthers()
Post-transaction invalidations notification.protected void
setFragmentModified(Fragment fragment)
protected void
setFragmentPristine(Fragment fragment)
protected Map<String,Serializable>
updateChangeToken(SimpleFragment hier)
Updates a change token in the main fragment, and returns the condition to check.
-
-
-
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
-
SEL_WARN_THRESHOLD_DEFAULT
public static final String SEL_WARN_THRESHOLD_DEFAULT
- See Also:
- Constant Field Values
-
POS_COMPARATOR
protected static final SimpleFragment.FieldComparator POS_COMPARATOR
-
VER_CREATED_COMPARATOR
protected static final SimpleFragment.FieldComparator VER_CREATED_COMPARATOR
-
model
protected final Model model
-
mapper
protected final RowMapper mapper
-
session
protected final SessionImpl session
-
versionAclMode
protected final BaseSession.VersionAclMode versionAclMode
-
disableReadVersionPermission
protected final boolean disableReadVersionPermission
-
hierComplex
protected final SelectionContext hierComplex
-
hierNonComplex
public final SelectionContext hierNonComplex
-
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
orFragment.State.ABSENT
, or in some casesFragment.State.INVALIDATED_MODIFIED
orFragment.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.
-
modified
protected final Map<RowId,Fragment> modified
The fragments changed by the session.This contains fragment that are
Fragment.State.CREATED
,Fragment.State.MODIFIED
orFragment.State.DELETED
.
-
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.
-
-
Constructor Detail
-
PersistenceContext
public PersistenceContext(Model model, RowMapper mapper, SessionImpl session)
-
-
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).
-
isIdNew
protected boolean isIdNew(Serializable id)
-
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 methoddirtyBinaries
- set of ids, updated by this method
-
markInvalidated
protected void markInvalidated(VCSInvalidations invalidations)
Marks locally all the invalidations gathered by aMapper
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()
-
getIfPresent
protected Fragment getIfPresent(RowId rowId)
Gets a fragment, if present in the context.Called by
get(org.nuxeo.ecm.core.storage.sql.RowId, boolean)
, and by theMapper
to reuse known selection fragments.- Parameters:
rowId
- the fragment id- Returns:
- the fragment, or
null
if not found
-
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 idallowAbsent
-true
to return an absent fragment as an object instead ofnull
- Returns:
- the fragment, or
null
if none is found andallowAbsent
wasfalse
-
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 idallowAbsent
-true
to return an absent fragment as an object instead ofnull
cacheOnly
- only check memory, not the database- Returns:
- the fragment, or when
allowAbsent
isfalse
, anull
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
isfalse
.
-
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 idsallowAbsent
-true
to return an absent fragment as an object instead of skipping it- Returns:
- the fragments, in arbitrary order (no
null
s)
-
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, unlessallowAbsent
isfalse
in which case it will be skipped.- Parameters:
rowIds
- the list of rows or row idsallowAbsent
-true
to return an absent fragment as an object instead ofnull
- 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, unlessallowAbsent
isfalse
in which casenull
will be returned.- Parameters:
rowId
- the row or row id (may benull
)allowAbsent
-true
to return an absent fragment as an object instead ofnull
- 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 istrue
, 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.
-
getSeriesProxyIds
public List<Serializable> getSeriesProxyIds(Serializable versionSeriesId)
-
getTargetProxyIds
public List<Serializable> getTargetProxyIds(Serializable targetId)
-
getTargetProxies
public Set<Serializable> getTargetProxies(Set<Serializable> ids)
-
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
istrue
, returns the full path.If
fetch
isfalse
, 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.
-
getHier
protected SimpleFragment getHier(Serializable id, boolean allowAbsent)
-
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 idcomplexProp
- 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 idsourceId
- the node id to movedestId
- the node id before which to place the source node, ifnull
then move the source to the end
-
getChildHierByName
public SimpleFragment getChildHierByName(Serializable parentId, String name, boolean complexProp)
-
getChildren
public List<SimpleFragment> getChildren(Serializable parentId, String name, boolean complexProp)
Gets hier fragments for children.
-
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 sourceparentId
- the destination parent idname
- 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 copyparentId
- the destination parent idname
- the new nameafterRecordCopy
- 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 inlabel
- the version labelcheckinComment
- 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
-
-