HHH-16515 - Add o.h.engine.spi to nullness checking
Signed-off-by: Jan Schatteman <jschatte@redhat.com>
This commit is contained in:
parent
f84c2b56db
commit
7ff76bf6eb
|
@ -8,7 +8,18 @@ public final class Method extends Executable {
|
||||||
void invoke(@Nullable Object obj, @Nullable Object @Nullable ... args);
|
void invoke(@Nullable Object obj, @Nullable Object @Nullable ... args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final
|
public final class Field extends AccessibleObject implements Member {
|
||||||
class Field extends AccessibleObject implements Member {
|
|
||||||
public void set(Object obj, @Nullable Object value);
|
public void set(Object obj, @Nullable Object value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
package java.util;
|
||||||
|
|
||||||
|
|
||||||
|
public interface Queue<E> extends Collection<E> {
|
||||||
|
@Override
|
||||||
|
@EnsuresNonNullIf(expression="poll()", result=false)
|
||||||
|
@EnsuresNonNullIf(expression="peek()", result=false)
|
||||||
|
boolean isEmpty();
|
||||||
|
E poll();
|
||||||
|
E peek();
|
||||||
|
}
|
||||||
|
|
|
@ -6,4 +6,8 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public interface BasicLogger {
|
public interface BasicLogger {
|
||||||
void tracef(String format, @Nullable Object param1, @Nullable Object param2);
|
void tracef(String format, @Nullable Object param1, @Nullable Object param2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Logger {
|
||||||
|
void tracev(String format, @Nullable Object param1);
|
||||||
}
|
}
|
|
@ -487,7 +487,7 @@ checkerFramework {
|
||||||
extraJavacArgs = [
|
extraJavacArgs = [
|
||||||
'-AsuppressWarnings=initialization',
|
'-AsuppressWarnings=initialization',
|
||||||
// stubs is passed directly through options.compilerArgumentProviders
|
// stubs is passed directly through options.compilerArgumentProviders
|
||||||
'-AonlyDefs=^org\\.hibernate\\.(jdbc|exception|integrator|jpamodelgen|service|spi|pretty|property\\.access|stat|engine\\.(config|jndi|profile|transaction)|(action|context|bytecode)\\.spi)\\.'
|
'-AonlyDefs=^org\\.hibernate\\.(jdbc|exception|integrator|jpamodelgen|service|spi|pretty|property\\.access|stat|engine\\.(config|jndi|profile|spi|transaction)|(action|context|bytecode)\\.spi)\\.'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.collection.mutation.InsertRowsCoordinator;
|
import org.hibernate.persister.collection.mutation.InsertRowsCoordinator;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persistent collections are treated as value objects by Hibernate.
|
* Persistent collections are treated as value objects by Hibernate.
|
||||||
* They have no independent existence beyond the entity holding a
|
* They have no independent existence beyond the entity holding a
|
||||||
|
@ -82,7 +84,7 @@ public interface PersistentCollection<E> extends LazyInitializable {
|
||||||
* @param role The collection role
|
* @param role The collection role
|
||||||
* @param snapshot The snapshot state
|
* @param snapshot The snapshot state
|
||||||
*/
|
*/
|
||||||
void setSnapshot(Object key, String role, Serializable snapshot);
|
void setSnapshot(@Nullable Object key, @Nullable String role, @Nullable Serializable snapshot);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After flushing, clear any "queued" additions, since the
|
* After flushing, clear any "queued" additions, since the
|
||||||
|
|
|
@ -10,6 +10,8 @@ import org.hibernate.graph.GraphSemantic;
|
||||||
import org.hibernate.graph.spi.AppliedGraph;
|
import org.hibernate.graph.spi.AppliedGraph;
|
||||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulates a JPA EntityGraph provided through a JPQL query hint. Converts the fetches into a list of AST
|
* Encapsulates a JPA EntityGraph provided through a JPQL query hint. Converts the fetches into a list of AST
|
||||||
* FromElements. The logic is kept here as much as possible in order to make it easy to remove this in the future,
|
* FromElements. The logic is kept here as much as possible in order to make it easy to remove this in the future,
|
||||||
|
@ -28,12 +30,12 @@ public class EntityGraphQueryHint implements AppliedGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GraphSemantic getSemantic() {
|
public @Nullable GraphSemantic getSemantic() {
|
||||||
return delegate.getSemantic();
|
return delegate.getSemantic();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RootGraphImplementor<?> getGraph() {
|
public @Nullable RootGraphImplementor<?> getGraph() {
|
||||||
return delegate.getGraph();
|
return delegate.getGraph();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@ import org.hibernate.engine.internal.NonNullableTransientDependencies;
|
||||||
import org.hibernate.event.spi.EventSource;
|
import org.hibernate.event.spi.EventSource;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.internal.EntityCollectionPart;
|
import org.hibernate.metamodel.mapping.internal.EntityCollectionPart;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
@ -57,6 +56,8 @@ import org.hibernate.type.EntityType;
|
||||||
import org.hibernate.type.ForeignKeyDirection;
|
import org.hibernate.type.ForeignKeyDirection;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
|
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -511,7 +512,7 @@ public class ActionQueue {
|
||||||
prepareActions( collectionQueuedOps );
|
prepareActions( collectionQueuedOps );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareActions(ExecutableList<?> queue) throws HibernateException {
|
private void prepareActions(@Nullable ExecutableList<?> queue) throws HibernateException {
|
||||||
if ( queue == null ) {
|
if ( queue == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -583,7 +584,7 @@ public class ActionQueue {
|
||||||
return areTablesToBeUpdated( unresolvedInsertions, tables );
|
return areTablesToBeUpdated( unresolvedInsertions, tables );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean areTablesToBeUpdated(ExecutableList<?> actions, Set<? extends Serializable> tableSpaces) {
|
private static boolean areTablesToBeUpdated(@Nullable ExecutableList<?> actions, Set<? extends Serializable> tableSpaces) {
|
||||||
if ( actions == null || actions.isEmpty() ) {
|
if ( actions == null || actions.isEmpty() ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -617,7 +618,7 @@ public class ActionQueue {
|
||||||
* @param list The list of Executable elements to be performed
|
* @param list The list of Executable elements to be performed
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private <E extends ComparableExecutable> void executeActions(ExecutableList<E> list)
|
private <E extends ComparableExecutable> void executeActions(@Nullable ExecutableList<E> list)
|
||||||
throws HibernateException {
|
throws HibernateException {
|
||||||
if ( list == null || list.isEmpty() ) {
|
if ( list == null || list.isEmpty() ) {
|
||||||
return;
|
return;
|
||||||
|
@ -651,8 +652,10 @@ public class ActionQueue {
|
||||||
// Strictly speaking, only a subset of the list may have been processed if a RuntimeException occurs.
|
// Strictly speaking, only a subset of the list may have been processed if a RuntimeException occurs.
|
||||||
// We still invalidate all spaces. I don't see this as a big deal - after all, RuntimeExceptions are
|
// We still invalidate all spaces. I don't see this as a big deal - after all, RuntimeExceptions are
|
||||||
// unexpected.
|
// unexpected.
|
||||||
invalidateSpaces( list.getQuerySpaces().toArray(StringHelper.EMPTY_STRINGS) );
|
invalidateSpaces( list.getQuerySpaces().toArray(new String[0]) );
|
||||||
}
|
}
|
||||||
|
// @NonNull String @Nullable [] - array nullable, elements not
|
||||||
|
// @Nullable String @NonNull [] - elements nullable, array not
|
||||||
}
|
}
|
||||||
|
|
||||||
list.clear();
|
list.clear();
|
||||||
|
@ -676,7 +679,7 @@ public class ActionQueue {
|
||||||
*
|
*
|
||||||
* @param spaces The spaces to invalidate
|
* @param spaces The spaces to invalidate
|
||||||
*/
|
*/
|
||||||
private void invalidateSpaces(String[] spaces) {
|
private void invalidateSpaces(String @Nullable [] spaces) {
|
||||||
if ( spaces != null && spaces.length > 0 ) {
|
if ( spaces != null && spaces.length > 0 ) {
|
||||||
for ( String space : spaces ) {
|
for ( String space : spaces ) {
|
||||||
if ( afterTransactionProcesses == null ) {
|
if ( afterTransactionProcesses == null ) {
|
||||||
|
@ -708,7 +711,7 @@ public class ActionQueue {
|
||||||
+ "]";
|
+ "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String toString(ExecutableList<?> q) {
|
private static String toString(@Nullable ExecutableList<?> q) {
|
||||||
return q == null ? "ExecutableList{size=0}" : q.toString();
|
return q == null ? "ExecutableList{size=0}" : q.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,7 +861,7 @@ public class ActionQueue {
|
||||||
|| nonempty( collectionCreations );
|
|| nonempty( collectionCreations );
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean nonempty(ExecutableList<?> list) {
|
private boolean nonempty(@Nullable ExecutableList<?> list) {
|
||||||
return list != null && !list.isEmpty();
|
return list != null && !list.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -984,7 +987,7 @@ public class ActionQueue {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void register(T process) {
|
public void register(@Nullable T process) {
|
||||||
if ( process != null ) {
|
if ( process != null ) {
|
||||||
processes.add( process );
|
processes.add( process );
|
||||||
}
|
}
|
||||||
|
@ -1051,7 +1054,7 @@ public class ActionQueue {
|
||||||
|
|
||||||
if ( session.getFactory().getSessionFactoryOptions().isQueryCacheEnabled() ) {
|
if ( session.getFactory().getSessionFactoryOptions().isQueryCacheEnabled() ) {
|
||||||
session.getFactory().getCache().getTimestampsCache().invalidate(
|
session.getFactory().getCache().getTimestampsCache().invalidate(
|
||||||
querySpacesToInvalidate.toArray(StringHelper.EMPTY_STRINGS),
|
querySpacesToInvalidate.toArray(new String[0]),
|
||||||
session
|
session
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1149,7 +1152,7 @@ public class ActionQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDirectDependency(Type type, Object value, IdentityHashMap<Object, InsertInfo> insertInfosByEntity) {
|
private void addDirectDependency(Type type, @Nullable Object value, IdentityHashMap<Object, InsertInfo> insertInfosByEntity) {
|
||||||
if ( type.isEntityType() && value != null ) {
|
if ( type.isEntityType() && value != null ) {
|
||||||
final EntityType entityType = (EntityType) type;
|
final EntityType entityType = (EntityType) type;
|
||||||
final InsertInfo insertInfo = insertInfosByEntity.get( value );
|
final InsertInfo insertInfo = insertInfosByEntity.get( value );
|
||||||
|
@ -1209,7 +1212,7 @@ public class ActionQueue {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(@Nullable Object o) {
|
||||||
if ( this == o ) {
|
if ( this == o ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1305,7 +1308,7 @@ public class ActionQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int schedule(InsertInfo[] insertInfos, List<InsertInfo> insertInfosToSchedule, int schedulePosition) {
|
private int schedule(InsertInfo [] insertInfos, List<InsertInfo> insertInfosToSchedule, int schedulePosition) {
|
||||||
final InsertInfo[] newInsertInfos = new InsertInfo[insertInfos.length];
|
final InsertInfo[] newInsertInfos = new InsertInfo[insertInfos.length];
|
||||||
// The bitset is there to quickly query if an index is already scheduled
|
// The bitset is there to quickly query if an index is already scheduled
|
||||||
final BitSet bitSet = new BitSet(insertInfos.length);
|
final BitSet bitSet = new BitSet(insertInfos.length);
|
||||||
|
|
|
@ -8,6 +8,8 @@ package org.hibernate.engine.spi;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies a named association belonging to a particular
|
* Identifies a named association belonging to a particular
|
||||||
* entity instance. Used to record the fact that an association
|
* entity instance. Used to record the fact that an association
|
||||||
|
@ -31,7 +33,7 @@ public final class AssociationKey implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(@Nullable Object o) {
|
||||||
if ( this == o ) {
|
if ( this == o ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,9 @@ import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keeps track of:<ul>
|
* Keeps track of:<ul>
|
||||||
* <li>entity and collection keys that are available for batch fetching</li>
|
* <li>entity and collection keys that are available for batch fetching</li>
|
||||||
|
@ -45,22 +48,22 @@ public class BatchFetchQueue {
|
||||||
* A map of {@link SubselectFetch subselect-fetch descriptors} keyed by the
|
* A map of {@link SubselectFetch subselect-fetch descriptors} keyed by the
|
||||||
* {@link EntityKey} against which the descriptor is registered.
|
* {@link EntityKey} against which the descriptor is registered.
|
||||||
*/
|
*/
|
||||||
private Map<EntityKey, SubselectFetch> subselectsByEntityKey;
|
private @Nullable Map<EntityKey, SubselectFetch> subselectsByEntityKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to hold information about the entities that are currently eligible for batch-fetching. Ultimately
|
* Used to hold information about the entities that are currently eligible for batch-fetching. Ultimately
|
||||||
* used by {@link #getBatchLoadableEntityIds} to build entity load batches.
|
* used by {@link #getBatchLoadableEntityIds} to build entity load batches.
|
||||||
* <p>
|
* <p>
|
||||||
* A Map structure is used to segment the keys by entity type since loading can only be done for a particular entity
|
* A Map structure is used to segment the keys by entity type since loading can only be done for a particular entity
|
||||||
* type at a time.
|
* type at a time.
|
||||||
*/
|
*/
|
||||||
private Map <String,LinkedHashSet<EntityKey>> batchLoadableEntityKeys;
|
private @Nullable Map <String,LinkedHashSet<EntityKey>> batchLoadableEntityKeys;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to hold information about the collections that are currently eligible for batch-fetching. Ultimately
|
* Used to hold information about the collections that are currently eligible for batch-fetching. Ultimately
|
||||||
* used by {@link #getCollectionBatch} to build collection load batches.
|
* used by {@link #getCollectionBatch} to build collection load batches.
|
||||||
*/
|
*/
|
||||||
private Map<String, LinkedHashMap<CollectionEntry, PersistentCollection<?>>> batchLoadableCollections;
|
private @Nullable Map<String, LinkedHashMap<CollectionEntry, PersistentCollection<?>>> batchLoadableCollections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a queue for the given context.
|
* Constructs a queue for the given context.
|
||||||
|
@ -92,7 +95,7 @@ public class BatchFetchQueue {
|
||||||
* @return The fetch descriptor; may return null if no subselect fetch queued for
|
* @return The fetch descriptor; may return null if no subselect fetch queued for
|
||||||
* this entity key.
|
* this entity key.
|
||||||
*/
|
*/
|
||||||
public SubselectFetch getSubselect(EntityKey key) {
|
public @Nullable SubselectFetch getSubselect(EntityKey key) {
|
||||||
if ( subselectsByEntityKey == null ) {
|
if ( subselectsByEntityKey == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -165,9 +168,9 @@ public class BatchFetchQueue {
|
||||||
* if necessary
|
* if necessary
|
||||||
*/
|
*/
|
||||||
public void removeBatchLoadableEntityKey(EntityKey key) {
|
public void removeBatchLoadableEntityKey(EntityKey key) {
|
||||||
if ( batchLoadableEntityKeys != null
|
if ( key.isBatchLoadable( context.getSession().getLoadQueryInfluencers() )
|
||||||
&& key.isBatchLoadable( context.getSession().getLoadQueryInfluencers() ) ) {
|
&& batchLoadableEntityKeys != null ) {
|
||||||
final LinkedHashSet<EntityKey> set = batchLoadableEntityKeys.get( key.getEntityName() );
|
final LinkedHashSet<EntityKey> set = batchLoadableEntityKeys.get( key.getEntityName() );
|
||||||
if ( set != null ) {
|
if ( set != null ) {
|
||||||
set.remove( key );
|
set.remove( key );
|
||||||
}
|
}
|
||||||
|
@ -175,12 +178,11 @@ public class BatchFetchQueue {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intended for test usage. Really has no use-case in Hibernate proper.
|
* Intended for test usage. Really has no use-case in Hibernate proper.
|
||||||
*/
|
*/
|
||||||
public boolean containsEntityKey(EntityKey key) {
|
public boolean containsEntityKey(EntityKey key) {
|
||||||
if ( batchLoadableEntityKeys != null
|
if ( key.isBatchLoadable( context.getSession().getLoadQueryInfluencers() ) && batchLoadableEntityKeys != null ) {
|
||||||
&& key.isBatchLoadable( context.getSession().getLoadQueryInfluencers() ) ) {
|
LinkedHashSet<EntityKey> set = batchLoadableEntityKeys.get( key.getEntityName() );
|
||||||
LinkedHashSet<EntityKey> set = batchLoadableEntityKeys.get( key.getEntityName() );
|
|
||||||
if ( set != null ) {
|
if ( set != null ) {
|
||||||
return set.contains( key );
|
return set.contains( key );
|
||||||
}
|
}
|
||||||
|
@ -189,7 +191,7 @@ public class BatchFetchQueue {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A "collector" form of {@link #getBatchLoadableEntityIds}. Useful
|
* A "collector" form of {@link #getBatchLoadableEntityIds}. Useful
|
||||||
* in cases where we want a specially created array/container - allows
|
* in cases where we want a specially created array/container - allows
|
||||||
* creation of concretely typed array for ARRAY param binding to ensure
|
* creation of concretely typed array for ARRAY param binding to ensure
|
||||||
* the driver does not need to cast/copy the values array.
|
* the driver does not need to cast/copy the values array.
|
||||||
|
@ -197,7 +199,7 @@ public class BatchFetchQueue {
|
||||||
public <T> void collectBatchLoadableEntityIds(
|
public <T> void collectBatchLoadableEntityIds(
|
||||||
final int domainBatchSize,
|
final int domainBatchSize,
|
||||||
IndexedConsumer<T> collector,
|
IndexedConsumer<T> collector,
|
||||||
final T loadingId,
|
final @NonNull T loadingId,
|
||||||
final EntityMappingType entityDescriptor) {
|
final EntityMappingType entityDescriptor) {
|
||||||
// make sure we load the id being loaded in the batch!
|
// make sure we load the id being loaded in the batch!
|
||||||
collector.accept( 0, loadingId );
|
collector.accept( 0, loadingId );
|
||||||
|
@ -206,7 +208,7 @@ public class BatchFetchQueue {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final LinkedHashSet<EntityKey> set = batchLoadableEntityKeys.get( entityDescriptor.getEntityName() );
|
final LinkedHashSet<EntityKey> set = batchLoadableEntityKeys.get( entityDescriptor.getEntityName() );
|
||||||
if ( set == null ) {
|
if ( set == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -248,7 +250,7 @@ public class BatchFetchQueue {
|
||||||
* complex algorithm that tries to grab keys registered immediately after
|
* complex algorithm that tries to grab keys registered immediately after
|
||||||
* the given key.
|
* the given key.
|
||||||
*/
|
*/
|
||||||
public Object[] getBatchLoadableEntityIds(
|
public Object [] getBatchLoadableEntityIds(
|
||||||
final EntityMappingType entityDescriptor,
|
final EntityMappingType entityDescriptor,
|
||||||
final Object loadingId,
|
final Object loadingId,
|
||||||
final int maxBatchSize) {
|
final int maxBatchSize) {
|
||||||
|
@ -328,6 +330,7 @@ public class BatchFetchQueue {
|
||||||
batchLoadableCollections = CollectionHelper.mapOfSize( 12 );
|
batchLoadableCollections = CollectionHelper.mapOfSize( 12 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert persister != null : "@AssumeAssertion(nullness)";
|
||||||
final LinkedHashMap<CollectionEntry, PersistentCollection<?>> map =
|
final LinkedHashMap<CollectionEntry, PersistentCollection<?>> map =
|
||||||
batchLoadableCollections.computeIfAbsent(
|
batchLoadableCollections.computeIfAbsent(
|
||||||
persister.getRole(),
|
persister.getRole(),
|
||||||
|
@ -343,11 +346,13 @@ public class BatchFetchQueue {
|
||||||
* if necessary
|
* if necessary
|
||||||
*/
|
*/
|
||||||
public void removeBatchLoadableCollection(CollectionEntry ce) {
|
public void removeBatchLoadableCollection(CollectionEntry ce) {
|
||||||
|
final CollectionPersister persister = ce.getLoadedPersister();
|
||||||
if ( batchLoadableCollections == null ) {
|
if ( batchLoadableCollections == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
assert persister != null : "@AssumeAssertion(nullness)";
|
||||||
LinkedHashMap<CollectionEntry, PersistentCollection<?>> map =
|
LinkedHashMap<CollectionEntry, PersistentCollection<?>> map =
|
||||||
batchLoadableCollections.get( ce.getLoadedPersister().getRole() );
|
batchLoadableCollections.get( persister.getRole() );
|
||||||
if ( map != null ) {
|
if ( map != null ) {
|
||||||
map.remove( ce );
|
map.remove( ce );
|
||||||
}
|
}
|
||||||
|
@ -355,7 +360,7 @@ public class BatchFetchQueue {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A "collector" form of {@link #getCollectionBatch}. Useful
|
* A "collector" form of {@link #getCollectionBatch}. Useful
|
||||||
* in cases where we want a specially created array/container - allows
|
* in cases where we want a specially created array/container - allows
|
||||||
* creation of concretely typed array for ARRAY param binding to ensure
|
* creation of concretely typed array for ARRAY param binding to ensure
|
||||||
* the driver does not need to cast/copy the values array.
|
* the driver does not need to cast/copy the values array.
|
||||||
|
@ -363,7 +368,7 @@ public class BatchFetchQueue {
|
||||||
public <T> void collectBatchLoadableCollectionKeys(
|
public <T> void collectBatchLoadableCollectionKeys(
|
||||||
int batchSize,
|
int batchSize,
|
||||||
IndexedConsumer<T> collector,
|
IndexedConsumer<T> collector,
|
||||||
T keyBeingLoaded,
|
@NonNull T keyBeingLoaded,
|
||||||
PluralAttributeMapping pluralAttributeMapping) {
|
PluralAttributeMapping pluralAttributeMapping) {
|
||||||
collector.accept( 0, keyBeingLoaded );
|
collector.accept( 0, keyBeingLoaded );
|
||||||
|
|
||||||
|
@ -383,9 +388,10 @@ public class BatchFetchQueue {
|
||||||
|
|
||||||
for ( Entry<CollectionEntry, PersistentCollection<?>> me : map.entrySet() ) {
|
for ( Entry<CollectionEntry, PersistentCollection<?>> me : map.entrySet() ) {
|
||||||
final CollectionEntry ce = me.getKey();
|
final CollectionEntry ce = me.getKey();
|
||||||
|
final Object loadedKey = ce.getLoadedKey();
|
||||||
final PersistentCollection<?> collection = me.getValue();
|
final PersistentCollection<?> collection = me.getValue();
|
||||||
|
|
||||||
if ( ce.getLoadedKey() == null ) {
|
if ( loadedKey == null ) {
|
||||||
// the loadedKey of the collectionEntry might be null as it might have been reset to null
|
// the loadedKey of the collectionEntry might be null as it might have been reset to null
|
||||||
// (see for example Collections.processDereferencedCollection()
|
// (see for example Collections.processDereferencedCollection()
|
||||||
// and CollectionEntry.afterAction())
|
// and CollectionEntry.afterAction())
|
||||||
|
@ -407,21 +413,21 @@ public class BatchFetchQueue {
|
||||||
|
|
||||||
final boolean isEqual = pluralAttributeMapping.getKeyDescriptor().areEqual(
|
final boolean isEqual = pluralAttributeMapping.getKeyDescriptor().areEqual(
|
||||||
keyBeingLoaded,
|
keyBeingLoaded,
|
||||||
ce.getLoadedKey(),
|
loadedKey,
|
||||||
context.getSession()
|
context.getSession()
|
||||||
);
|
);
|
||||||
// final boolean isEqual = collectionPersister.getKeyType().isEqual(
|
// final boolean isEqual = collectionPersister.getKeyType().isEqual(
|
||||||
// id,
|
// id,
|
||||||
// ce.getLoadedKey(),
|
// loadedKey,
|
||||||
// collectionPersister.getFactory()
|
// collectionPersister.getFactory()
|
||||||
// );
|
// );
|
||||||
|
|
||||||
if ( isEqual ) {
|
if ( isEqual ) {
|
||||||
end = i;
|
end = i;
|
||||||
}
|
}
|
||||||
else if ( !isCached( ce.getLoadedKey(), pluralAttributeMapping.getCollectionDescriptor() ) ) {
|
else if ( !isCached( loadedKey, pluralAttributeMapping.getCollectionDescriptor() ) ) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
collector.accept( i++, (T) ce.getLoadedKey() );
|
collector.accept( i++, (T) loadedKey );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( i == batchSize ) {
|
if ( i == batchSize ) {
|
||||||
|
@ -444,7 +450,7 @@ public class BatchFetchQueue {
|
||||||
* @param batchSize the maximum number of keys to return
|
* @param batchSize the maximum number of keys to return
|
||||||
* @return an array of collection keys, of length batchSize (padded with nulls)
|
* @return an array of collection keys, of length batchSize (padded with nulls)
|
||||||
*/
|
*/
|
||||||
public Object[] getCollectionBatch(
|
public Object [] getCollectionBatch(
|
||||||
final CollectionPersister collectionPersister,
|
final CollectionPersister collectionPersister,
|
||||||
final Object id,
|
final Object id,
|
||||||
final int batchSize) {
|
final int batchSize) {
|
||||||
|
@ -465,9 +471,10 @@ public class BatchFetchQueue {
|
||||||
if ( map != null ) {
|
if ( map != null ) {
|
||||||
for ( Entry<CollectionEntry, PersistentCollection<?>> me : map.entrySet() ) {
|
for ( Entry<CollectionEntry, PersistentCollection<?>> me : map.entrySet() ) {
|
||||||
final CollectionEntry ce = me.getKey();
|
final CollectionEntry ce = me.getKey();
|
||||||
|
final Object loadedKey = ce.getLoadedKey();
|
||||||
final PersistentCollection<?> collection = me.getValue();
|
final PersistentCollection<?> collection = me.getValue();
|
||||||
|
|
||||||
if ( ce.getLoadedKey() == null ) {
|
if ( loadedKey == null ) {
|
||||||
// the loadedKey of the collectionEntry might be null as it might have been reset to null
|
// the loadedKey of the collectionEntry might be null as it might have been reset to null
|
||||||
// (see for example Collections.processDereferencedCollection()
|
// (see for example Collections.processDereferencedCollection()
|
||||||
// and CollectionEntry.afterAction())
|
// and CollectionEntry.afterAction())
|
||||||
|
@ -488,7 +495,7 @@ public class BatchFetchQueue {
|
||||||
|
|
||||||
final boolean isEqual = collectionPersister.getKeyType().isEqual(
|
final boolean isEqual = collectionPersister.getKeyType().isEqual(
|
||||||
id,
|
id,
|
||||||
ce.getLoadedKey(),
|
loadedKey,
|
||||||
collectionPersister.getFactory()
|
collectionPersister.getFactory()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -496,8 +503,8 @@ public class BatchFetchQueue {
|
||||||
end = i;
|
end = i;
|
||||||
//checkForEnd = false;
|
//checkForEnd = false;
|
||||||
}
|
}
|
||||||
else if ( !isCached( ce.getLoadedKey(), collectionPersister ) ) {
|
else if ( !isCached( loadedKey, collectionPersister ) ) {
|
||||||
keys[i++] = ce.getLoadedKey();
|
keys[i++] = loadedKey;
|
||||||
//count++;
|
//count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.hibernate.collection.spi.AbstractPersistentCollection;
|
||||||
import org.hibernate.collection.spi.PersistentCollection;
|
import org.hibernate.collection.spi.PersistentCollection;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
import org.hibernate.internal.util.NullnessUtil;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.pretty.MessageHelper;
|
import org.hibernate.pretty.MessageHelper;
|
||||||
|
|
||||||
|
@ -21,6 +22,9 @@ import java.io.ObjectOutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.initialization.qual.UnderInitialization;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We need an entry to tell us all about the current state
|
* We need an entry to tell us all about the current state
|
||||||
* of a collection with respect to its persistent state
|
* of a collection with respect to its persistent state
|
||||||
|
@ -33,14 +37,14 @@ public final class CollectionEntry implements Serializable {
|
||||||
//ATTRIBUTES MAINTAINED BETWEEN FLUSH CYCLES
|
//ATTRIBUTES MAINTAINED BETWEEN FLUSH CYCLES
|
||||||
|
|
||||||
// session-start/post-flush persistent state
|
// session-start/post-flush persistent state
|
||||||
private Serializable snapshot;
|
private @Nullable Serializable snapshot;
|
||||||
// allow the CollectionSnapshot to be serialized
|
// allow the CollectionSnapshot to be serialized
|
||||||
private String role;
|
private @Nullable String role;
|
||||||
|
|
||||||
// "loaded" means the reference that is consistent
|
// "loaded" means the reference that is consistent
|
||||||
// with the current database state
|
// with the current database state
|
||||||
private transient CollectionPersister loadedPersister;
|
private transient @Nullable CollectionPersister loadedPersister;
|
||||||
private Object loadedKey;
|
private @Nullable Object loadedKey;
|
||||||
|
|
||||||
// ATTRIBUTES USED ONLY DURING FLUSH CYCLE
|
// ATTRIBUTES USED ONLY DURING FLUSH CYCLE
|
||||||
|
|
||||||
|
@ -56,8 +60,8 @@ public final class CollectionEntry implements Serializable {
|
||||||
private transient boolean ignore;
|
private transient boolean ignore;
|
||||||
|
|
||||||
// "current" means the reference that was found during flush()
|
// "current" means the reference that was found during flush()
|
||||||
private transient CollectionPersister currentPersister;
|
private transient @Nullable CollectionPersister currentPersister;
|
||||||
private transient Object currentKey;
|
private transient @Nullable Object currentKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For newly wrapped collections, or dereferenced collection wrappers
|
* For newly wrapped collections, or dereferenced collection wrappers
|
||||||
|
@ -88,7 +92,9 @@ public final class CollectionEntry implements Serializable {
|
||||||
//collection.clearDirty()
|
//collection.clearDirty()
|
||||||
|
|
||||||
this.loadedKey = loadedKey;
|
this.loadedKey = loadedKey;
|
||||||
setLoadedPersister( loadedPersister );
|
|
||||||
|
this.loadedPersister = loadedPersister;
|
||||||
|
this.role = ( loadedPersister == null ? null : loadedPersister.getRole() );
|
||||||
|
|
||||||
collection.setSnapshot( loadedKey, role, null );
|
collection.setSnapshot( loadedKey, role, null );
|
||||||
|
|
||||||
|
@ -106,7 +112,8 @@ public final class CollectionEntry implements Serializable {
|
||||||
//collection.clearDirty()
|
//collection.clearDirty()
|
||||||
|
|
||||||
this.loadedKey = loadedKey;
|
this.loadedKey = loadedKey;
|
||||||
setLoadedPersister( loadedPersister );
|
this.loadedPersister = loadedPersister;
|
||||||
|
this.role = ( loadedPersister == null ? null : loadedPersister.getRole() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,9 +125,8 @@ public final class CollectionEntry implements Serializable {
|
||||||
ignore = false;
|
ignore = false;
|
||||||
|
|
||||||
loadedKey = collection.getKey();
|
loadedKey = collection.getKey();
|
||||||
setLoadedPersister(
|
loadedPersister = factory.getRuntimeMetamodels().getMappingMetamodel().getCollectionDescriptor( collection.getRole() );
|
||||||
factory.getRuntimeMetamodels().getMappingMetamodel().getCollectionDescriptor( collection.getRole() )
|
this.role = ( loadedPersister == null ? null : loadedPersister.getRole() );
|
||||||
);
|
|
||||||
|
|
||||||
snapshot = collection.getStoredSnapshot();
|
snapshot = collection.getStoredSnapshot();
|
||||||
}
|
}
|
||||||
|
@ -132,10 +138,10 @@ public final class CollectionEntry implements Serializable {
|
||||||
* @see #deserialize
|
* @see #deserialize
|
||||||
*/
|
*/
|
||||||
private CollectionEntry(
|
private CollectionEntry(
|
||||||
String role,
|
@Nullable String role,
|
||||||
Serializable snapshot,
|
Serializable snapshot,
|
||||||
Object loadedKey,
|
Object loadedKey,
|
||||||
SessionFactoryImplementor factory) {
|
@Nullable SessionFactoryImplementor factory) {
|
||||||
this.role = role;
|
this.role = role;
|
||||||
this.snapshot = snapshot;
|
this.snapshot = snapshot;
|
||||||
this.loadedKey = loadedKey;
|
this.loadedKey = loadedKey;
|
||||||
|
@ -176,7 +182,7 @@ public final class CollectionEntry implements Serializable {
|
||||||
if ( nonMutableChange ) {
|
if ( nonMutableChange ) {
|
||||||
throw new HibernateException(
|
throw new HibernateException(
|
||||||
"changed an immutable collection instance: " +
|
"changed an immutable collection instance: " +
|
||||||
MessageHelper.collectionInfoString( loadedPersister.getRole(), getLoadedKey() )
|
MessageHelper.collectionInfoString( NullnessUtil.castNonNull( loadedPersister ).getRole(), getLoadedKey() )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,12 +205,12 @@ public final class CollectionEntry implements Serializable {
|
||||||
|
|
||||||
public void postInitialize(PersistentCollection<?> collection) throws HibernateException {
|
public void postInitialize(PersistentCollection<?> collection) throws HibernateException {
|
||||||
final CollectionPersister loadedPersister = getLoadedPersister();
|
final CollectionPersister loadedPersister = getLoadedPersister();
|
||||||
snapshot = loadedPersister.isMutable()
|
snapshot = loadedPersister != null && loadedPersister.isMutable()
|
||||||
? collection.getSnapshot( loadedPersister )
|
? collection.getSnapshot( loadedPersister )
|
||||||
: null;
|
: null;
|
||||||
collection.setSnapshot( loadedKey, role, snapshot );
|
collection.setSnapshot( loadedKey, role, snapshot );
|
||||||
final SharedSessionContractImplementor session = ((AbstractPersistentCollection<?>) collection).getSession();
|
final SharedSessionContractImplementor session = ((AbstractPersistentCollection<?>) collection).getSession();
|
||||||
if ( session.getLoadQueryInfluencers().effectivelyBatchLoadable( loadedPersister ) ) {
|
if ( loadedPersister != null && session.getLoadQueryInfluencers().effectivelyBatchLoadable( loadedPersister ) ) {
|
||||||
session.getPersistenceContextInternal()
|
session.getPersistenceContextInternal()
|
||||||
.getBatchFetchQueue()
|
.getBatchFetchQueue()
|
||||||
.removeBatchLoadableCollection( this );
|
.removeBatchLoadableCollection( this );
|
||||||
|
@ -236,21 +242,21 @@ public final class CollectionEntry implements Serializable {
|
||||||
if ( resnapshot ) {
|
if ( resnapshot ) {
|
||||||
snapshot = loadedPersister == null || !loadedPersister.isMutable() ?
|
snapshot = loadedPersister == null || !loadedPersister.isMutable() ?
|
||||||
null :
|
null :
|
||||||
collection.getSnapshot( loadedPersister ); //re-snapshot
|
collection.getSnapshot( NullnessUtil.castNonNull( loadedPersister ) ); //re-snapshot
|
||||||
}
|
}
|
||||||
|
|
||||||
collection.postAction();
|
collection.postAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getKey() {
|
public @Nullable Object getKey() {
|
||||||
return getLoadedKey();
|
return getLoadedKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRole() {
|
public @Nullable String getRole() {
|
||||||
return role;
|
return role;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Serializable getSnapshot() {
|
public @Nullable Serializable getSnapshot() {
|
||||||
return snapshot;
|
return snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,17 +281,17 @@ public final class CollectionEntry implements Serializable {
|
||||||
fromMerge = true;
|
fromMerge = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setLoadedPersister(CollectionPersister persister) {
|
private void setLoadedPersister(@Nullable CollectionPersister persister) {
|
||||||
loadedPersister = persister;
|
loadedPersister = persister;
|
||||||
setRole( persister == null ? null : persister.getRole() );
|
setRole( persister == null ? null : persister.getRole() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void afterDeserialize(SessionFactoryImplementor factory) {
|
void afterDeserialize(@Nullable SessionFactoryImplementor factory) {
|
||||||
if ( factory == null ) {
|
if ( factory == null ) {
|
||||||
loadedPersister = null;
|
loadedPersister = null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
loadedPersister = factory.getRuntimeMetamodels().getMappingMetamodel().getCollectionDescriptor( role );
|
loadedPersister = factory.getRuntimeMetamodels().getMappingMetamodel().getCollectionDescriptor( NullnessUtil.castNonNull( role ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,11 +343,11 @@ public final class CollectionEntry implements Serializable {
|
||||||
return ignore;
|
return ignore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CollectionPersister getCurrentPersister() {
|
public @Nullable CollectionPersister getCurrentPersister() {
|
||||||
return currentPersister;
|
return currentPersister;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCurrentPersister(CollectionPersister currentPersister) {
|
public void setCurrentPersister(@Nullable CollectionPersister currentPersister) {
|
||||||
this.currentPersister = currentPersister;
|
this.currentPersister = currentPersister;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,26 +355,26 @@ public final class CollectionEntry implements Serializable {
|
||||||
* This is only available late during the flush
|
* This is only available late during the flush
|
||||||
* cycle
|
* cycle
|
||||||
*/
|
*/
|
||||||
public Object getCurrentKey() {
|
public @Nullable Object getCurrentKey() {
|
||||||
return currentKey;
|
return currentKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCurrentKey(Object currentKey) {
|
public void setCurrentKey(@Nullable Object currentKey) {
|
||||||
this.currentKey = currentKey;
|
this.currentKey = currentKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is only available late during the flush cycle
|
* This is only available late during the flush cycle
|
||||||
*/
|
*/
|
||||||
public CollectionPersister getLoadedPersister() {
|
public @Nullable CollectionPersister getLoadedPersister() {
|
||||||
return loadedPersister;
|
return loadedPersister;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getLoadedKey() {
|
public @Nullable Object getLoadedKey() {
|
||||||
return loadedKey;
|
return loadedKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRole(String role) {
|
public void setRole(@Nullable String role) {
|
||||||
this.role = role;
|
this.role = role;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,9 +404,10 @@ public final class CollectionEntry implements Serializable {
|
||||||
// does the collection already have
|
// does the collection already have
|
||||||
// it's own up-to-date snapshot?
|
// it's own up-to-date snapshot?
|
||||||
final CollectionPersister loadedPersister = getLoadedPersister();
|
final CollectionPersister loadedPersister = getLoadedPersister();
|
||||||
|
Serializable snapshot = getSnapshot();
|
||||||
return collection.wasInitialized() &&
|
return collection.wasInitialized() &&
|
||||||
( loadedPersister ==null || loadedPersister.isMutable() ) &&
|
( loadedPersister == null || loadedPersister.isMutable() ) &&
|
||||||
collection.isSnapshotEmpty( getSnapshot() );
|
(snapshot != null ? collection.isSnapshotEmpty( snapshot ) : true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@ import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.pretty.MessageHelper;
|
import org.hibernate.pretty.MessageHelper;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uniquely identifies a collection instance in a particular session.
|
* Uniquely identifies a collection instance in a particular session.
|
||||||
*
|
*
|
||||||
|
@ -39,7 +41,7 @@ public final class CollectionKey implements Serializable {
|
||||||
|
|
||||||
private CollectionKey(
|
private CollectionKey(
|
||||||
String role,
|
String role,
|
||||||
Object key,
|
@Nullable Object key,
|
||||||
Type keyType,
|
Type keyType,
|
||||||
SessionFactoryImplementor factory) {
|
SessionFactoryImplementor factory) {
|
||||||
this.role = role;
|
this.role = role;
|
||||||
|
@ -77,7 +79,7 @@ public final class CollectionKey implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object other) {
|
public boolean equals(final @Nullable Object other) {
|
||||||
if ( this == other ) {
|
if ( this == other ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -127,7 +129,8 @@ public final class CollectionKey implements Serializable {
|
||||||
(String) ois.readObject(),
|
(String) ois.readObject(),
|
||||||
ois.readObject(),
|
ois.readObject(),
|
||||||
(Type) ois.readObject(),
|
(Type) ois.readObject(),
|
||||||
(session == null ? null : session.getFactory())
|
// Should never be able to be null
|
||||||
|
session.getFactory()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,12 @@ import org.hibernate.Incubating;
|
||||||
import org.hibernate.graph.GraphSemantic;
|
import org.hibernate.graph.GraphSemantic;
|
||||||
import org.hibernate.graph.spi.AppliedGraph;
|
import org.hibernate.graph.spi.AppliedGraph;
|
||||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||||
|
import org.hibernate.internal.util.NullnessUtil;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Think of this as the composite modeling of a graph
|
* Think of this as the composite modeling of a graph
|
||||||
* and the semantic.
|
* and the semantic.
|
||||||
|
@ -33,8 +36,8 @@ public class EffectiveEntityGraph implements AppliedGraph, Serializable {
|
||||||
|
|
||||||
private final boolean allowOverwrite;
|
private final boolean allowOverwrite;
|
||||||
|
|
||||||
private GraphSemantic semantic;
|
private @Nullable GraphSemantic semantic;
|
||||||
private RootGraphImplementor<?> graph;
|
private @Nullable RootGraphImplementor<?> graph;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @implSpec I explicitly made this constructor package protected
|
* @implSpec I explicitly made this constructor package protected
|
||||||
|
@ -59,12 +62,12 @@ public class EffectiveEntityGraph implements AppliedGraph, Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GraphSemantic getSemantic() {
|
public @Nullable GraphSemantic getSemantic() {
|
||||||
return semantic;
|
return semantic;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RootGraphImplementor<?> getGraph() {
|
public @Nullable RootGraphImplementor<?> getGraph() {
|
||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +78,7 @@ public class EffectiveEntityGraph implements AppliedGraph, Serializable {
|
||||||
* @throws IllegalArgumentException Thrown if the semantic is null
|
* @throws IllegalArgumentException Thrown if the semantic is null
|
||||||
* @throws IllegalStateException If previous state is still available (hasn't been cleared).
|
* @throws IllegalStateException If previous state is still available (hasn't been cleared).
|
||||||
*/
|
*/
|
||||||
public void applyGraph(RootGraphImplementor<?> graph, GraphSemantic semantic) {
|
public void applyGraph(RootGraphImplementor<?> graph, @Nullable GraphSemantic semantic) {
|
||||||
if ( semantic == null ) {
|
if ( semantic == null ) {
|
||||||
throw new IllegalArgumentException( "Graph semantic cannot be null" );
|
throw new IllegalArgumentException( "Graph semantic cannot be null" );
|
||||||
}
|
}
|
||||||
|
@ -107,7 +110,7 @@ public class EffectiveEntityGraph implements AppliedGraph, Serializable {
|
||||||
* @throws IllegalArgumentException If both kinds of graphs were present in the properties/hints
|
* @throws IllegalArgumentException If both kinds of graphs were present in the properties/hints
|
||||||
* @throws IllegalStateException If previous state is still available (hasn't been cleared).
|
* @throws IllegalStateException If previous state is still available (hasn't been cleared).
|
||||||
*/
|
*/
|
||||||
public void applyConfiguredGraph(Map<String,?> properties) {
|
public void applyConfiguredGraph(@Nullable Map<String,?> properties) {
|
||||||
if ( properties == null || properties.isEmpty() ) {
|
if ( properties == null || properties.isEmpty() ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -138,6 +141,7 @@ public class EffectiveEntityGraph implements AppliedGraph, Serializable {
|
||||||
applyGraph( fetchHint, GraphSemantic.FETCH );
|
applyGraph( fetchHint, GraphSemantic.FETCH );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
assert loadHint != null : "@AssumeAssertion(nullness)";
|
||||||
applyGraph( loadHint, GraphSemantic.LOAD );
|
applyGraph( loadHint, GraphSemantic.LOAD );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@ import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.pretty.MessageHelper;
|
import org.hibernate.pretty.MessageHelper;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uniquely identifies of an entity instance in a particular Session by identifier.
|
* Uniquely identifies of an entity instance in a particular Session by identifier.
|
||||||
* Note that it's only safe to be used within the scope of a Session: it doesn't consider for example the tenantId
|
* Note that it's only safe to be used within the scope of a Session: it doesn't consider for example the tenantId
|
||||||
|
@ -44,7 +46,7 @@ public final class EntityKey implements Serializable {
|
||||||
* @param id The entity id
|
* @param id The entity id
|
||||||
* @param persister The entity persister
|
* @param persister The entity persister
|
||||||
*/
|
*/
|
||||||
public EntityKey(Object id, EntityPersister persister) {
|
public EntityKey(@Nullable Object id, EntityPersister persister) {
|
||||||
this.persister = persister;
|
this.persister = persister;
|
||||||
if ( id == null ) {
|
if ( id == null ) {
|
||||||
throw new AssertionFailure( "null identifier (" + persister.getEntityName() + ")" );
|
throw new AssertionFailure( "null identifier (" + persister.getEntityName() + ")" );
|
||||||
|
@ -82,7 +84,7 @@ public final class EntityKey implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(@Nullable Object other) {
|
||||||
if ( this == other ) {
|
if ( this == other ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,10 @@ import java.io.Serializable;
|
||||||
import org.hibernate.pretty.MessageHelper;
|
import org.hibernate.pretty.MessageHelper;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.initialization.qual.UnderInitialization;
|
||||||
|
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to uniquely key an entity instance in relation to a particular session
|
* Used to uniquely key an entity instance in relation to a particular session
|
||||||
* by some unique property reference, as opposed to identifier.
|
* by some unique property reference, as opposed to identifier.
|
||||||
|
@ -41,7 +45,7 @@ public class EntityUniqueKey implements Serializable {
|
||||||
this.entityName = entityName;
|
this.entityName = entityName;
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.keyType = keyType;
|
this.keyType = keyType;
|
||||||
this.hashCode = generateHashCode( factory );
|
this.hashCode = generateHashCode( entityName, uniqueKeyName, keyType, key, factory );
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEntityName() {
|
public String getEntityName() {
|
||||||
|
@ -56,7 +60,7 @@ public class EntityUniqueKey implements Serializable {
|
||||||
return uniqueKeyName;
|
return uniqueKeyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int generateHashCode(SessionFactoryImplementor factory) {
|
public static int generateHashCode(String entityName, String uniqueKeyName, Type keyType, Object key, SessionFactoryImplementor factory) {
|
||||||
int result = 17;
|
int result = 17;
|
||||||
result = 37 * result + entityName.hashCode();
|
result = 37 * result + entityName.hashCode();
|
||||||
result = 37 * result + uniqueKeyName.hashCode();
|
result = 37 * result + uniqueKeyName.hashCode();
|
||||||
|
@ -70,7 +74,10 @@ public class EntityUniqueKey implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(@Nullable Object other) {
|
||||||
|
if ( other == null || other.getClass() != EntityUniqueKey.class ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
EntityUniqueKey that = (EntityUniqueKey) other;
|
EntityUniqueKey that = (EntityUniqueKey) other;
|
||||||
return that != null && that.entityName.equals( entityName )
|
return that != null && that.entityName.equals( entityName )
|
||||||
&& that.uniqueKeyName.equals( uniqueKeyName )
|
&& that.uniqueKeyName.equals( uniqueKeyName )
|
||||||
|
|
|
@ -22,6 +22,8 @@ import org.hibernate.action.spi.Executable;
|
||||||
import org.hibernate.event.spi.EventSource;
|
import org.hibernate.event.spi.EventSource;
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of {@link Executable executeble actions}. Responsible for
|
* A list of {@link Executable executeble actions}. Responsible for
|
||||||
* {@linkplain #sort() sorting} the executables, and calculating the
|
* {@linkplain #sort() sorting} the executables, and calculating the
|
||||||
|
@ -47,7 +49,7 @@ public class ExecutableList<E extends ComparableExecutable>
|
||||||
|
|
||||||
private final ArrayList<E> executables;
|
private final ArrayList<E> executables;
|
||||||
|
|
||||||
private final Sorter<E> sorter;
|
private final @Nullable Sorter<E> sorter;
|
||||||
private final boolean requiresSorting;
|
private final boolean requiresSorting;
|
||||||
private boolean sorted;
|
private boolean sorted;
|
||||||
|
|
||||||
|
@ -57,7 +59,7 @@ public class ExecutableList<E extends ComparableExecutable>
|
||||||
* invalidate cache regions as it is exposed from {@link #getQuerySpaces}. This value
|
* invalidate cache regions as it is exposed from {@link #getQuerySpaces}. This value
|
||||||
* being {@code null} indicates that the query spaces should be calculated.
|
* being {@code null} indicates that the query spaces should be calculated.
|
||||||
*/
|
*/
|
||||||
private transient Set<Serializable> querySpaces;
|
private transient @Nullable Set<Serializable> querySpaces;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance with the default settings.
|
* Creates a new instance with the default settings.
|
||||||
|
@ -296,9 +298,10 @@ public class ExecutableList<E extends ComparableExecutable>
|
||||||
oos.writeInt( -1 );
|
oos.writeInt( -1 );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
final Set<Serializable> qs = querySpaces;
|
||||||
oos.writeInt( querySpaces.size() );
|
oos.writeInt( querySpaces.size() );
|
||||||
// these are always String, why we treat them as Serializable instead is beyond me...
|
// these are always String, why we treat them as Serializable instead is beyond me...
|
||||||
for ( Serializable querySpace : querySpaces ) {
|
for ( Serializable querySpace : qs ) {
|
||||||
oos.writeUTF( querySpace.toString() );
|
oos.writeUTF( querySpace.toString() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,10 +332,12 @@ public class ExecutableList<E extends ComparableExecutable>
|
||||||
this.querySpaces = null;
|
this.querySpaces = null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
querySpaces = CollectionHelper.setOfSize( numberOfQuerySpaces );
|
// The line below is for CF nullness checking purposes.
|
||||||
|
final Set<Serializable> querySpaces = CollectionHelper.setOfSize( numberOfQuerySpaces );
|
||||||
for ( int i = 0; i < numberOfQuerySpaces; i++ ) {
|
for ( int i = 0; i < numberOfQuerySpaces; i++ ) {
|
||||||
querySpaces.add( in.readUTF() );
|
querySpaces.add( in.readUTF() );
|
||||||
}
|
}
|
||||||
|
this.querySpaces = querySpaces;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ package org.hibernate.engine.spi;
|
||||||
|
|
||||||
import org.hibernate.annotations.ResultCheckStyle;
|
import org.hibernate.annotations.ResultCheckStyle;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For persistence operations (INSERT, UPDATE, DELETE) what style of
|
* For persistence operations (INSERT, UPDATE, DELETE) what style of
|
||||||
* determining results (success/failure) is to be used.
|
* determining results (success/failure) is to be used.
|
||||||
|
@ -54,7 +56,7 @@ public enum ExecuteUpdateResultCheckStyle {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ExecuteUpdateResultCheckStyle fromResultCheckStyle(ResultCheckStyle style) {
|
public static @Nullable ExecuteUpdateResultCheckStyle fromResultCheckStyle(ResultCheckStyle style) {
|
||||||
switch (style) {
|
switch (style) {
|
||||||
case NONE:
|
case NONE:
|
||||||
return NONE;
|
return NONE;
|
||||||
|
@ -67,7 +69,7 @@ public enum ExecuteUpdateResultCheckStyle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ExecuteUpdateResultCheckStyle fromExternalName(String name) {
|
public static @Nullable ExecuteUpdateResultCheckStyle fromExternalName(String name) {
|
||||||
if ( name.equalsIgnoreCase( NONE.name ) ) {
|
if ( name.equalsIgnoreCase( NONE.name ) ) {
|
||||||
return NONE;
|
return NONE;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +84,7 @@ public enum ExecuteUpdateResultCheckStyle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ExecuteUpdateResultCheckStyle determineDefault(String customSql, boolean callable) {
|
public static ExecuteUpdateResultCheckStyle determineDefault(@Nullable String customSql, boolean callable) {
|
||||||
return customSql != null && callable ? PARAM : COUNT;
|
return customSql != null && callable ? PARAM : COUNT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the definition of a {@link org.hibernate.Filter filter}.
|
* Represents the definition of a {@link org.hibernate.Filter filter}.
|
||||||
* This information includes the {@linkplain #filterName name} of the
|
* This information includes the {@linkplain #filterName name} of the
|
||||||
|
@ -36,7 +38,7 @@ public class FilterDefinition implements Serializable {
|
||||||
*
|
*
|
||||||
* @param name The name of the filter for which this configuration is in effect.
|
* @param name The name of the filter for which this configuration is in effect.
|
||||||
*/
|
*/
|
||||||
public FilterDefinition(String name, String defaultCondition, Map<String, JdbcMapping> explicitParamJaMappings) {
|
public FilterDefinition(String name, String defaultCondition, @Nullable Map<String, JdbcMapping> explicitParamJaMappings) {
|
||||||
this.filterName = name;
|
this.filterName = name;
|
||||||
this.defaultFilterCondition = defaultCondition;
|
this.defaultFilterCondition = defaultCondition;
|
||||||
if ( explicitParamJaMappings != null ) {
|
if ( explicitParamJaMappings != null ) {
|
||||||
|
@ -59,7 +61,9 @@ public class FilterDefinition implements Serializable {
|
||||||
* @return The parameters named by this configuration.
|
* @return The parameters named by this configuration.
|
||||||
*/
|
*/
|
||||||
public Set<String> getParameterNames() {
|
public Set<String> getParameterNames() {
|
||||||
return explicitParamJaMappings.keySet();
|
// local variable instantiated for checkerframework nullness inference reasons
|
||||||
|
Set<String> keys = explicitParamJaMappings.keySet();
|
||||||
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,7 +73,7 @@ public class FilterDefinition implements Serializable {
|
||||||
*
|
*
|
||||||
* @return The type of the named parameter.
|
* @return The type of the named parameter.
|
||||||
*/
|
*/
|
||||||
public JdbcMapping getParameterJdbcMapping(String parameterName) {
|
public @Nullable JdbcMapping getParameterJdbcMapping(String parameterName) {
|
||||||
return explicitParamJaMappings.get( parameterName );
|
return explicitParamJaMappings.get( parameterName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ import org.hibernate.internal.CoreLogging;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A strategy for determining if an identifier value is an identifier of
|
* A strategy for determining if an identifier value is an identifier of
|
||||||
* a new transient instance or a previously persistent transient instance.
|
* a new transient instance or a previously persistent transient instance.
|
||||||
|
@ -23,7 +25,7 @@ import org.jboss.logging.Logger;
|
||||||
public class IdentifierValue implements UnsavedValueStrategy {
|
public class IdentifierValue implements UnsavedValueStrategy {
|
||||||
private static final Logger LOG = CoreLogging.logger( IdentifierValue.class );
|
private static final Logger LOG = CoreLogging.logger( IdentifierValue.class );
|
||||||
|
|
||||||
private final Object value;
|
private final @Nullable Object value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Always assume the transient instance is newly instantiated
|
* Always assume the transient instance is newly instantiated
|
||||||
|
@ -73,13 +75,13 @@ public class IdentifierValue implements UnsavedValueStrategy {
|
||||||
*/
|
*/
|
||||||
public static final IdentifierValue NULL = new IdentifierValue() {
|
public static final IdentifierValue NULL = new IdentifierValue() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean isUnsaved(Object id) {
|
public Boolean isUnsaved(@Nullable Object id) {
|
||||||
LOG.trace( "ID unsaved-value strategy NULL" );
|
LOG.trace( "ID unsaved-value strategy NULL" );
|
||||||
return id == null;
|
return id == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Serializable getDefaultValue(Object currentValue) {
|
public @Nullable Serializable getDefaultValue(Object currentValue) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,13 +96,13 @@ public class IdentifierValue implements UnsavedValueStrategy {
|
||||||
*/
|
*/
|
||||||
public static final IdentifierValue UNDEFINED = new IdentifierValue() {
|
public static final IdentifierValue UNDEFINED = new IdentifierValue() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean isUnsaved(Object id) {
|
public @Nullable Boolean isUnsaved(Object id) {
|
||||||
LOG.trace( "ID unsaved-value strategy UNDEFINED" );
|
LOG.trace( "ID unsaved-value strategy UNDEFINED" );
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Serializable getDefaultValue(Object currentValue) {
|
public @Nullable Serializable getDefaultValue(Object currentValue) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,13 +128,13 @@ public class IdentifierValue implements UnsavedValueStrategy {
|
||||||
* Does the given identifier belong to a new instance?
|
* Does the given identifier belong to a new instance?
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean isUnsaved(Object id) {
|
public @Nullable Boolean isUnsaved(@Nullable Object id) {
|
||||||
LOG.tracev( "ID unsaved-value: {0}", value );
|
LOG.tracev( "ID unsaved-value: {0}", value );
|
||||||
return id == null || id.equals( value );
|
return id == null || id.equals( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getDefaultValue(Object currentValue) {
|
public @Nullable Object getDefaultValue(@Nullable Object currentValue) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,10 +23,13 @@ import org.hibernate.graph.GraphSemantic;
|
||||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||||
import org.hibernate.internal.FilterImpl;
|
import org.hibernate.internal.FilterImpl;
|
||||||
import org.hibernate.internal.SessionCreationOptions;
|
import org.hibernate.internal.SessionCreationOptions;
|
||||||
|
import org.hibernate.internal.util.NullnessUtil;
|
||||||
import org.hibernate.loader.ast.spi.CascadingFetchProfile;
|
import org.hibernate.loader.ast.spi.CascadingFetchProfile;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import static java.util.Collections.emptySet;
|
import static java.util.Collections.emptySet;
|
||||||
import static org.hibernate.engine.FetchStyle.SUBSELECT;
|
import static org.hibernate.engine.FetchStyle.SUBSELECT;
|
||||||
|
|
||||||
|
@ -51,7 +54,7 @@ public class LoadQueryInfluencers implements Serializable {
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
public static final LoadQueryInfluencers NONE = new LoadQueryInfluencers();
|
public static final LoadQueryInfluencers NONE = new LoadQueryInfluencers();
|
||||||
|
|
||||||
private final SessionFactoryImplementor sessionFactory;
|
private final @Nullable SessionFactoryImplementor sessionFactory;
|
||||||
|
|
||||||
private CascadingFetchProfile enabledCascadingFetchProfile;
|
private CascadingFetchProfile enabledCascadingFetchProfile;
|
||||||
|
|
||||||
|
@ -85,7 +88,7 @@ public class LoadQueryInfluencers implements Serializable {
|
||||||
subselectFetchEnabled = options.isSubselectFetchEnabled();
|
subselectFetchEnabled = options.isSubselectFetchEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public EffectiveEntityGraph applyEntityGraph(RootGraphImplementor<?> rootGraph, GraphSemantic graphSemantic) {
|
public EffectiveEntityGraph applyEntityGraph(@Nullable RootGraphImplementor<?> rootGraph, @Nullable GraphSemantic graphSemantic) {
|
||||||
final EffectiveEntityGraph effectiveEntityGraph = getEffectiveEntityGraph();
|
final EffectiveEntityGraph effectiveEntityGraph = getEffectiveEntityGraph();
|
||||||
if ( graphSemantic != null ) {
|
if ( graphSemantic != null ) {
|
||||||
if ( rootGraph == null ) {
|
if ( rootGraph == null ) {
|
||||||
|
@ -96,7 +99,7 @@ public class LoadQueryInfluencers implements Serializable {
|
||||||
return effectiveEntityGraph;
|
return effectiveEntityGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SessionFactoryImplementor getSessionFactory() {
|
public @Nullable SessionFactoryImplementor getSessionFactory() {
|
||||||
return sessionFactory;
|
return sessionFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +189,7 @@ public class LoadQueryInfluencers implements Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Filter getEnabledFilter(String filterName) {
|
public @Nullable Filter getEnabledFilter(String filterName) {
|
||||||
if ( enabledFilters == null ) {
|
if ( enabledFilters == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -197,7 +200,7 @@ public class LoadQueryInfluencers implements Serializable {
|
||||||
|
|
||||||
public Filter enableFilter(String filterName) {
|
public Filter enableFilter(String filterName) {
|
||||||
checkMutability();
|
checkMutability();
|
||||||
FilterImpl filter = new FilterImpl( sessionFactory.getFilterDefinition( filterName ) );
|
FilterImpl filter = new FilterImpl( NullnessUtil.castNonNull( sessionFactory ).getFilterDefinition( filterName ) );
|
||||||
if ( enabledFilters == null ) {
|
if ( enabledFilters == null ) {
|
||||||
this.enabledFilters = new HashMap<>();
|
this.enabledFilters = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
@ -223,7 +226,7 @@ public class LoadQueryInfluencers implements Serializable {
|
||||||
return filter.getParameter( parsed[1] );
|
return filter.getParameter( parsed[1] );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] parseFilterParameterName(String filterParameterName) {
|
public static String [] parseFilterParameterName(String filterParameterName) {
|
||||||
int dot = filterParameterName.lastIndexOf( '.' );
|
int dot = filterParameterName.lastIndexOf( '.' );
|
||||||
if ( dot <= 0 ) {
|
if ( dot <= 0 ) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
|
@ -274,7 +277,7 @@ public class LoadQueryInfluencers implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Internal
|
@Internal
|
||||||
public HashSet<String> adjustFetchProfiles(Set<String> disabledFetchProfiles, Set<String> enabledFetchProfiles) {
|
public @Nullable HashSet<String> adjustFetchProfiles(@Nullable Set<String> disabledFetchProfiles, @Nullable Set<String> enabledFetchProfiles) {
|
||||||
final HashSet<String> oldFetchProfiles =
|
final HashSet<String> oldFetchProfiles =
|
||||||
hasEnabledFetchProfiles() ? new HashSet<>( enabledFetchProfileNames ) : null;
|
hasEnabledFetchProfiles() ? new HashSet<>( enabledFetchProfileNames ) : null;
|
||||||
if ( disabledFetchProfiles != null && enabledFetchProfileNames != null ) {
|
if ( disabledFetchProfiles != null && enabledFetchProfileNames != null ) {
|
||||||
|
@ -353,7 +356,7 @@ public class LoadQueryInfluencers implements Serializable {
|
||||||
private boolean isSubselectFetchEnabledInProfile(CollectionPersister persister) {
|
private boolean isSubselectFetchEnabledInProfile(CollectionPersister persister) {
|
||||||
if ( hasEnabledFetchProfiles() ) {
|
if ( hasEnabledFetchProfiles() ) {
|
||||||
for ( String profile : getEnabledFetchProfileNames() ) {
|
for ( String profile : getEnabledFetchProfileNames() ) {
|
||||||
final FetchProfile fetchProfile = sessionFactory.getFetchProfile( profile );
|
final FetchProfile fetchProfile = persister.getFactory().getFetchProfile( profile ) ;
|
||||||
if ( fetchProfile != null ) {
|
if ( fetchProfile != null ) {
|
||||||
final Fetch fetch = fetchProfile.getFetchByRole( persister.getRole() );
|
final Fetch fetch = fetchProfile.getFetchByRole( persister.getRole() );
|
||||||
if ( fetch != null && fetch.getMethod() == SUBSELECT) {
|
if ( fetch != null && fetch.getMethod() == SUBSELECT) {
|
||||||
|
@ -382,7 +385,7 @@ public class LoadQueryInfluencers implements Serializable {
|
||||||
private boolean hasSubselectLoadableCollectionsEnabledInProfile(EntityPersister persister) {
|
private boolean hasSubselectLoadableCollectionsEnabledInProfile(EntityPersister persister) {
|
||||||
if ( hasEnabledFetchProfiles() ) {
|
if ( hasEnabledFetchProfiles() ) {
|
||||||
for ( String profile : getEnabledFetchProfileNames() ) {
|
for ( String profile : getEnabledFetchProfileNames() ) {
|
||||||
if ( sessionFactory.getFetchProfile( profile )
|
if ( persister.getFactory().getFetchProfile( profile )
|
||||||
.hasSubselectLoadableCollectionsEnabled( persister ) ) {
|
.hasSubselectLoadableCollectionsEnabled( persister ) ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ import org.hibernate.engine.internal.ManagedTypeHelper;
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
import org.hibernate.proxy.ProxyConfiguration;
|
import org.hibernate.proxy.ProxyConfiguration;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For a full explanation of the purpose of this interface see {@link ManagedTypeHelper}.
|
* For a full explanation of the purpose of this interface see {@link ManagedTypeHelper}.
|
||||||
*
|
*
|
||||||
|
@ -22,46 +24,46 @@ import org.hibernate.proxy.ProxyConfiguration;
|
||||||
@Internal
|
@Internal
|
||||||
public interface PrimeAmongSecondarySupertypes {
|
public interface PrimeAmongSecondarySupertypes {
|
||||||
|
|
||||||
default ManagedEntity asManagedEntity() {
|
default @Nullable ManagedEntity asManagedEntity() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
default PersistentAttributeInterceptable asPersistentAttributeInterceptable() {
|
default @Nullable PersistentAttributeInterceptable asPersistentAttributeInterceptable() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
default SelfDirtinessTracker asSelfDirtinessTracker() {
|
default @Nullable SelfDirtinessTracker asSelfDirtinessTracker() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Included for consistency but doesn't seem to be used?
|
//Included for consistency but doesn't seem to be used?
|
||||||
default Managed asManaged() {
|
default @Nullable Managed asManaged() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Included for consistency but doesn't seem to be used?
|
//Included for consistency but doesn't seem to be used?
|
||||||
default ManagedComposite asManagedComposite() {
|
default @Nullable ManagedComposite asManagedComposite() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Included for consistency but doesn't seem to be used?
|
//Included for consistency but doesn't seem to be used?
|
||||||
default ManagedMappedSuperclass asManagedMappedSuperclass() {
|
default @Nullable ManagedMappedSuperclass asManagedMappedSuperclass() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
default CompositeOwner asCompositeOwner() {
|
default @Nullable CompositeOwner asCompositeOwner() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
default CompositeTracker asCompositeTracker() {
|
default @Nullable CompositeTracker asCompositeTracker() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
default HibernateProxy asHibernateProxy() {
|
default @Nullable HibernateProxy asHibernateProxy() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
default ProxyConfiguration asProxyConfiguration() {
|
default @Nullable ProxyConfiguration asProxyConfiguration() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,7 @@ import jakarta.persistence.criteria.CriteriaDelete;
|
||||||
import jakarta.persistence.criteria.CriteriaQuery;
|
import jakarta.persistence.criteria.CriteriaQuery;
|
||||||
import jakarta.persistence.criteria.CriteriaUpdate;
|
import jakarta.persistence.criteria.CriteriaUpdate;
|
||||||
import jakarta.persistence.metamodel.Metamodel;
|
import jakarta.persistence.metamodel.Metamodel;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper class that delegates all method invocations to a delegate instance of
|
* A wrapper class that delegates all method invocations to a delegate instance of
|
||||||
|
@ -165,7 +166,7 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityPersister getEntityPersister(String entityName, Object object) throws HibernateException {
|
public EntityPersister getEntityPersister(@Nullable String entityName, Object object) throws HibernateException {
|
||||||
return delegate.getEntityPersister( entityName, object );
|
return delegate.getEntityPersister( entityName, object );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -853,22 +854,22 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T find(Class<T> entityClass, Object primaryKey) {
|
public <T> @Nullable T find(Class<T> entityClass, Object primaryKey) {
|
||||||
return delegate.find( entityClass, primaryKey );
|
return delegate.find( entityClass, primaryKey );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T find(Class<T> entityClass, Object primaryKey, Map<String, Object> properties) {
|
public <T> @Nullable T find(Class<T> entityClass, Object primaryKey, Map<String, Object> properties) {
|
||||||
return delegate.find( entityClass, primaryKey, properties );
|
return delegate.find( entityClass, primaryKey, properties );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode) {
|
public <T> @Nullable T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode) {
|
||||||
return delegate.find( entityClass, primaryKey, lockMode );
|
return delegate.find( entityClass, primaryKey, lockMode );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode, Map<String, Object> properties) {
|
public <T> @Nullable T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode, Map<String, Object> properties) {
|
||||||
return delegate.find( entityClass, primaryKey, lockMode, properties );
|
return delegate.find( entityClass, primaryKey, lockMode, properties );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ import jakarta.persistence.criteria.CriteriaDelete;
|
||||||
import jakarta.persistence.criteria.CriteriaQuery;
|
import jakarta.persistence.criteria.CriteriaQuery;
|
||||||
import jakarta.persistence.criteria.CriteriaUpdate;
|
import jakarta.persistence.criteria.CriteriaUpdate;
|
||||||
import jakarta.persistence.metamodel.Metamodel;
|
import jakarta.persistence.metamodel.Metamodel;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This helper class allows decorating a Session instance, while the
|
* This helper class allows decorating a Session instance, while the
|
||||||
|
@ -809,22 +810,22 @@ public class SessionLazyDelegator implements Session {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T find(Class<T> entityClass, Object primaryKey) {
|
public <T> @Nullable T find(Class<T> entityClass, Object primaryKey) {
|
||||||
return this.lazySession.get().find( entityClass, primaryKey );
|
return this.lazySession.get().find( entityClass, primaryKey );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T find(Class<T> entityClass, Object primaryKey, Map<String, Object> properties) {
|
public <T> @Nullable T find(Class<T> entityClass, Object primaryKey, Map<String, Object> properties) {
|
||||||
return this.lazySession.get().find( entityClass, primaryKey, properties );
|
return this.lazySession.get().find( entityClass, primaryKey, properties );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode) {
|
public <T> @Nullable T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode) {
|
||||||
return this.lazySession.get().find( entityClass, primaryKey, lockMode );
|
return this.lazySession.get().find( entityClass, primaryKey, lockMode );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode, Map<String, Object> properties) {
|
public <T> @Nullable T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode, Map<String, Object> properties) {
|
||||||
return this.lazySession.get().find( entityClass, primaryKey, lockMode, properties );
|
return this.lazySession.get().find( entityClass, primaryKey, lockMode, properties );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import jakarta.persistence.FlushModeType;
|
import jakarta.persistence.FlushModeType;
|
||||||
import jakarta.persistence.TransactionRequiredException;
|
import jakarta.persistence.TransactionRequiredException;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import org.hibernate.CacheMode;
|
import org.hibernate.CacheMode;
|
||||||
import org.hibernate.FlushMode;
|
import org.hibernate.FlushMode;
|
||||||
|
@ -307,7 +308,7 @@ public interface SharedSessionContractImplementor
|
||||||
* @param entityName optional entity name
|
* @param entityName optional entity name
|
||||||
* @param object the entity instance
|
* @param object the entity instance
|
||||||
*/
|
*/
|
||||||
EntityPersister getEntityPersister(String entityName, Object object) throws HibernateException;
|
EntityPersister getEntityPersister(@Nullable String entityName, Object object) throws HibernateException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the entity instance associated with the given {@link EntityKey},
|
* Get the entity instance associated with the given {@link EntityKey},
|
||||||
|
|
|
@ -11,6 +11,8 @@ import jakarta.persistence.FlushModeType;
|
||||||
import jakarta.persistence.criteria.CriteriaDelete;
|
import jakarta.persistence.criteria.CriteriaDelete;
|
||||||
import jakarta.persistence.criteria.CriteriaQuery;
|
import jakarta.persistence.criteria.CriteriaQuery;
|
||||||
import jakarta.persistence.criteria.CriteriaUpdate;
|
import jakarta.persistence.criteria.CriteriaUpdate;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import org.hibernate.CacheMode;
|
import org.hibernate.CacheMode;
|
||||||
import org.hibernate.FlushMode;
|
import org.hibernate.FlushMode;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
@ -413,7 +415,7 @@ public class SharedSessionDelegatorBaseImpl implements SharedSessionContractImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityPersister getEntityPersister(String entityName, Object object) throws HibernateException {
|
public EntityPersister getEntityPersister(@Nullable String entityName, Object object) throws HibernateException {
|
||||||
return delegate.getEntityPersister( entityName, object );
|
return delegate.getEntityPersister( entityName, object );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ import java.io.Serializable;
|
||||||
import org.hibernate.internal.util.ValueHolder;
|
import org.hibernate.internal.util.ValueHolder;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An ordered pair of a value and its Hibernate type.
|
* An ordered pair of a value and its Hibernate type.
|
||||||
*
|
*
|
||||||
|
@ -28,7 +30,7 @@ public final class TypedValue implements Serializable {
|
||||||
public TypedValue(final Type type, final Object value) {
|
public TypedValue(final Type type, final Object value) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
initTransients();
|
this.hashcode = hashCode(type, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getValue() {
|
public Object getValue() {
|
||||||
|
@ -47,7 +49,7 @@ public final class TypedValue implements Serializable {
|
||||||
return hashcode.getValue();
|
return hashcode.getValue();
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(@Nullable Object other) {
|
||||||
if ( this == other ) {
|
if ( this == other ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -62,10 +64,10 @@ public final class TypedValue implements Serializable {
|
||||||
private void readObject(ObjectInputStream ois)
|
private void readObject(ObjectInputStream ois)
|
||||||
throws ClassNotFoundException, IOException {
|
throws ClassNotFoundException, IOException {
|
||||||
ois.defaultReadObject();
|
ois.defaultReadObject();
|
||||||
initTransients();
|
this.hashcode = hashCode(type, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initTransients() {
|
private static ValueHolder hashCode(Type type, Object value) {
|
||||||
this.hashcode = new ValueHolder<>( () -> value == null ? 0 : type.getHashCode( value ) );
|
return new ValueHolder<>( () -> value == null ? 0 : type.getHashCode( value ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.engine.spi;
|
package org.hibernate.engine.spi;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base contract for determining transient status versus detached status.
|
* The base contract for determining transient status versus detached status.
|
||||||
*
|
*
|
||||||
|
@ -21,7 +23,7 @@ public interface UnsavedValueStrategy {
|
||||||
* indicates the value does not corresponds to unsaved data (aka, detached state); {@code null} indicates that
|
* indicates the value does not corresponds to unsaved data (aka, detached state); {@code null} indicates that
|
||||||
* this strategy was not able to determine conclusively.
|
* this strategy was not able to determine conclusively.
|
||||||
*/
|
*/
|
||||||
Boolean isUnsaved(Object test);
|
@Nullable Boolean isUnsaved(@Nullable Object test);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a default value meant to indicate transience.
|
* Get a default value meant to indicate transience.
|
||||||
|
@ -30,5 +32,5 @@ public interface UnsavedValueStrategy {
|
||||||
*
|
*
|
||||||
* @return The default transience value.
|
* @return The default transience value.
|
||||||
*/
|
*/
|
||||||
Object getDefaultValue(Object currentValue);
|
@Nullable Object getDefaultValue(@Nullable Object currentValue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ import org.hibernate.internal.CoreLogging;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A strategy for determining if a version value is a version of
|
* A strategy for determining if a version value is a version of
|
||||||
* a new transient instance or a previously persistent transient instance.
|
* a new transient instance or a previously persistent transient instance.
|
||||||
|
@ -23,20 +25,20 @@ import org.jboss.logging.Logger;
|
||||||
public class VersionValue implements UnsavedValueStrategy {
|
public class VersionValue implements UnsavedValueStrategy {
|
||||||
private static final Logger LOG = CoreLogging.logger( VersionValue.class );
|
private static final Logger LOG = CoreLogging.logger( VersionValue.class );
|
||||||
|
|
||||||
private final Object value;
|
private final @Nullable Object value;
|
||||||
/**
|
/**
|
||||||
* Assume the transient instance is newly instantiated if the version
|
* Assume the transient instance is newly instantiated if the version
|
||||||
* is null, otherwise assume it is a detached instance.
|
* is null, otherwise assume it is a detached instance.
|
||||||
*/
|
*/
|
||||||
public static final VersionValue NULL = new VersionValue() {
|
public static final VersionValue NULL = new VersionValue() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean isUnsaved(Object version) {
|
public Boolean isUnsaved(@Nullable Object version) {
|
||||||
LOG.trace( "Version unsaved-value strategy NULL" );
|
LOG.trace( "Version unsaved-value strategy NULL" );
|
||||||
return version == null;
|
return version == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getDefaultValue(Object currentValue) {
|
public @Nullable Object getDefaultValue(Object currentValue) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +54,7 @@ public class VersionValue implements UnsavedValueStrategy {
|
||||||
*/
|
*/
|
||||||
public static final VersionValue UNDEFINED = new VersionValue() {
|
public static final VersionValue UNDEFINED = new VersionValue() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean isUnsaved(Object version) {
|
public @Nullable Boolean isUnsaved(@Nullable Object version) {
|
||||||
LOG.trace( "Version unsaved-value strategy UNDEFINED" );
|
LOG.trace( "Version unsaved-value strategy UNDEFINED" );
|
||||||
return version == null ? Boolean.TRUE : null;
|
return version == null ? Boolean.TRUE : null;
|
||||||
}
|
}
|
||||||
|
@ -75,7 +77,7 @@ public class VersionValue implements UnsavedValueStrategy {
|
||||||
public static final VersionValue NEGATIVE = new VersionValue() {
|
public static final VersionValue NEGATIVE = new VersionValue() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean isUnsaved(Object version) throws MappingException {
|
public Boolean isUnsaved(@Nullable Object version) throws MappingException {
|
||||||
LOG.trace( "Version unsaved-value strategy NEGATIVE" );
|
LOG.trace( "Version unsaved-value strategy NEGATIVE" );
|
||||||
if ( version == null ) {
|
if ( version == null ) {
|
||||||
return Boolean.TRUE;
|
return Boolean.TRUE;
|
||||||
|
@ -114,13 +116,13 @@ public class VersionValue implements UnsavedValueStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean isUnsaved(Object version) throws MappingException {
|
public @Nullable Boolean isUnsaved(@Nullable Object version) throws MappingException {
|
||||||
LOG.tracev( "Version unsaved-value: {0}", value );
|
LOG.tracev( "Version unsaved-value: {0}", value );
|
||||||
return version == null || version.equals( value );
|
return version == null || version.equals( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getDefaultValue(Object currentValue) {
|
public @Nullable Object getDefaultValue(@Nullable Object currentValue) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ package org.hibernate.graph.spi;
|
||||||
|
|
||||||
import org.hibernate.graph.GraphSemantic;
|
import org.hibernate.graph.GraphSemantic;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contract for anything a fetch/load graph can be applied
|
* Contract for anything a fetch/load graph can be applied
|
||||||
*
|
*
|
||||||
|
@ -17,10 +19,10 @@ public interface AppliedGraph {
|
||||||
/**
|
/**
|
||||||
* The applied graph
|
* The applied graph
|
||||||
*/
|
*/
|
||||||
RootGraphImplementor<?> getGraph();
|
@Nullable RootGraphImplementor<?> getGraph();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The semantic (fetch/load) under which the graph should be applied
|
* The semantic (fetch/load) under which the graph should be applied
|
||||||
*/
|
*/
|
||||||
GraphSemantic getSemantic();
|
@Nullable GraphSemantic getSemantic();
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ public final class StringHelper {
|
||||||
return string.length() - 1;
|
return string.length() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String join(String seperator, String[] strings) {
|
public static String join(String separator, String[] strings) {
|
||||||
int length = strings.length;
|
int length = strings.length;
|
||||||
if ( length == 0 ) {
|
if ( length == 0 ) {
|
||||||
return "";
|
return "";
|
||||||
|
@ -54,7 +54,7 @@ public final class StringHelper {
|
||||||
StringBuilder buf = new StringBuilder( length * firstStringLength )
|
StringBuilder buf = new StringBuilder( length * firstStringLength )
|
||||||
.append( strings[0] );
|
.append( strings[0] );
|
||||||
for ( int i = 1; i < length; i++ ) {
|
for ( int i = 1; i < length; i++ ) {
|
||||||
buf.append( seperator ).append( strings[i] );
|
buf.append( separator ).append( strings[i] );
|
||||||
}
|
}
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base descriptor, within the mapping model, for any part of the
|
* Base descriptor, within the mapping model, for any part of the
|
||||||
* application's domain model: an attribute, an entity identifier,
|
* application's domain model: an attribute, an entity identifier,
|
||||||
|
@ -200,7 +202,7 @@ public interface ModelPart extends MappingModelExpressible {
|
||||||
|
|
||||||
EntityMappingType findContainingEntityMapping();
|
EntityMappingType findContainingEntityMapping();
|
||||||
|
|
||||||
default boolean areEqual(Object one, Object other, SharedSessionContractImplementor session) {
|
default boolean areEqual(@Nullable Object one, @Nullable Object other, SharedSessionContractImplementor session) {
|
||||||
// NOTE : deepEquals to account for arrays (compound natural-id)
|
// NOTE : deepEquals to account for arrays (compound natural-id)
|
||||||
return Objects.deepEquals( one, other );
|
return Objects.deepEquals( one, other );
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import jakarta.persistence.CacheRetrieveMode;
|
import jakarta.persistence.CacheRetrieveMode;
|
||||||
import jakarta.persistence.CacheStoreMode;
|
import jakarta.persistence.CacheStoreMode;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import org.hibernate.FlushMode;
|
import org.hibernate.FlushMode;
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
|
@ -248,12 +249,12 @@ public class QueryOptionsImpl implements MutableQueryOptions, AppliedGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RootGraphImplementor<?> getGraph() {
|
public @Nullable RootGraphImplementor<?> getGraph() {
|
||||||
return rootGraph;
|
return rootGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GraphSemantic getSemantic() {
|
public @Nullable GraphSemantic getSemantic() {
|
||||||
return graphSemantic;
|
return graphSemantic;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue