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);
|
||||
}
|
||||
|
||||
public final
|
||||
class Field extends AccessibleObject implements Member {
|
||||
public final class Field extends AccessibleObject implements Member {
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -7,3 +7,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||
public interface BasicLogger {
|
||||
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 = [
|
||||
'-AsuppressWarnings=initialization',
|
||||
// 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.type.Type;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Persistent collections are treated as value objects by Hibernate.
|
||||
* 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 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
|
||||
|
|
|
@ -10,6 +10,8 @@ import org.hibernate.graph.GraphSemantic;
|
|||
import org.hibernate.graph.spi.AppliedGraph;
|
||||
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
|
||||
* 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
|
||||
public GraphSemantic getSemantic() {
|
||||
public @Nullable GraphSemantic getSemantic() {
|
||||
return delegate.getSemantic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RootGraphImplementor<?> getGraph() {
|
||||
public @Nullable RootGraphImplementor<?> getGraph() {
|
||||
return delegate.getGraph();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@ import org.hibernate.engine.internal.NonNullableTransientDependencies;
|
|||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.EntityCollectionPart;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
@ -57,6 +56,8 @@ import org.hibernate.type.EntityType;
|
|||
import org.hibernate.type.ForeignKeyDirection;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
|
||||
|
||||
/**
|
||||
|
@ -511,7 +512,7 @@ public class ActionQueue {
|
|||
prepareActions( collectionQueuedOps );
|
||||
}
|
||||
|
||||
private void prepareActions(ExecutableList<?> queue) throws HibernateException {
|
||||
private void prepareActions(@Nullable ExecutableList<?> queue) throws HibernateException {
|
||||
if ( queue == null ) {
|
||||
return;
|
||||
}
|
||||
|
@ -583,7 +584,7 @@ public class ActionQueue {
|
|||
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() ) {
|
||||
return false;
|
||||
}
|
||||
|
@ -617,7 +618,7 @@ public class ActionQueue {
|
|||
* @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 {
|
||||
if ( list == null || list.isEmpty() ) {
|
||||
return;
|
||||
|
@ -651,8 +652,10 @@ public class ActionQueue {
|
|||
// 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
|
||||
// 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();
|
||||
|
@ -676,7 +679,7 @@ public class ActionQueue {
|
|||
*
|
||||
* @param spaces The spaces to invalidate
|
||||
*/
|
||||
private void invalidateSpaces(String[] spaces) {
|
||||
private void invalidateSpaces(String @Nullable [] spaces) {
|
||||
if ( spaces != null && spaces.length > 0 ) {
|
||||
for ( String space : spaces ) {
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -858,7 +861,7 @@ public class ActionQueue {
|
|||
|| nonempty( collectionCreations );
|
||||
}
|
||||
|
||||
private boolean nonempty(ExecutableList<?> list) {
|
||||
private boolean nonempty(@Nullable ExecutableList<?> list) {
|
||||
return list != null && !list.isEmpty();
|
||||
}
|
||||
|
||||
|
@ -984,7 +987,7 @@ public class ActionQueue {
|
|||
this.session = session;
|
||||
}
|
||||
|
||||
public void register(T process) {
|
||||
public void register(@Nullable T process) {
|
||||
if ( process != null ) {
|
||||
processes.add( process );
|
||||
}
|
||||
|
@ -1051,7 +1054,7 @@ public class ActionQueue {
|
|||
|
||||
if ( session.getFactory().getSessionFactoryOptions().isQueryCacheEnabled() ) {
|
||||
session.getFactory().getCache().getTimestampsCache().invalidate(
|
||||
querySpacesToInvalidate.toArray(StringHelper.EMPTY_STRINGS),
|
||||
querySpacesToInvalidate.toArray(new String[0]),
|
||||
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 ) {
|
||||
final EntityType entityType = (EntityType) type;
|
||||
final InsertInfo insertInfo = insertInfosByEntity.get( value );
|
||||
|
@ -1209,7 +1212,7 @@ public class ActionQueue {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if ( this == o ) {
|
||||
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];
|
||||
// The bitset is there to quickly query if an index is already scheduled
|
||||
final BitSet bitSet = new BitSet(insertInfos.length);
|
||||
|
|
|
@ -8,6 +8,8 @@ package org.hibernate.engine.spi;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Identifies a named association belonging to a particular
|
||||
* entity instance. Used to record the fact that an association
|
||||
|
@ -31,7 +33,7 @@ public final class AssociationKey implements Serializable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Keeps track of:<ul>
|
||||
* <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
|
||||
* {@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.
|
||||
* <p>
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
private Map<String, LinkedHashMap<CollectionEntry, PersistentCollection<?>>> batchLoadableCollections;
|
||||
private @Nullable Map<String, LinkedHashMap<CollectionEntry, PersistentCollection<?>>> batchLoadableCollections;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* this entity key.
|
||||
*/
|
||||
public SubselectFetch getSubselect(EntityKey key) {
|
||||
public @Nullable SubselectFetch getSubselect(EntityKey key) {
|
||||
if ( subselectsByEntityKey == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -165,9 +168,9 @@ public class BatchFetchQueue {
|
|||
* if necessary
|
||||
*/
|
||||
public void removeBatchLoadableEntityKey(EntityKey key) {
|
||||
if ( batchLoadableEntityKeys != null
|
||||
&& key.isBatchLoadable( context.getSession().getLoadQueryInfluencers() ) ) {
|
||||
final LinkedHashSet<EntityKey> set = batchLoadableEntityKeys.get( key.getEntityName() );
|
||||
if ( key.isBatchLoadable( context.getSession().getLoadQueryInfluencers() )
|
||||
&& batchLoadableEntityKeys != null ) {
|
||||
final LinkedHashSet<EntityKey> set = batchLoadableEntityKeys.get( key.getEntityName() );
|
||||
if ( set != null ) {
|
||||
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) {
|
||||
if ( batchLoadableEntityKeys != null
|
||||
&& key.isBatchLoadable( context.getSession().getLoadQueryInfluencers() ) ) {
|
||||
LinkedHashSet<EntityKey> set = batchLoadableEntityKeys.get( key.getEntityName() );
|
||||
if ( key.isBatchLoadable( context.getSession().getLoadQueryInfluencers() ) && batchLoadableEntityKeys != null ) {
|
||||
LinkedHashSet<EntityKey> set = batchLoadableEntityKeys.get( key.getEntityName() );
|
||||
if ( set != null ) {
|
||||
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
|
||||
* creation of concretely typed array for ARRAY param binding to ensure
|
||||
* the driver does not need to cast/copy the values array.
|
||||
|
@ -197,7 +199,7 @@ public class BatchFetchQueue {
|
|||
public <T> void collectBatchLoadableEntityIds(
|
||||
final int domainBatchSize,
|
||||
IndexedConsumer<T> collector,
|
||||
final T loadingId,
|
||||
final @NonNull T loadingId,
|
||||
final EntityMappingType entityDescriptor) {
|
||||
// make sure we load the id being loaded in the batch!
|
||||
collector.accept( 0, loadingId );
|
||||
|
@ -206,7 +208,7 @@ public class BatchFetchQueue {
|
|||
return;
|
||||
}
|
||||
|
||||
final LinkedHashSet<EntityKey> set = batchLoadableEntityKeys.get( entityDescriptor.getEntityName() );
|
||||
final LinkedHashSet<EntityKey> set = batchLoadableEntityKeys.get( entityDescriptor.getEntityName() );
|
||||
if ( set == null ) {
|
||||
return;
|
||||
}
|
||||
|
@ -248,7 +250,7 @@ public class BatchFetchQueue {
|
|||
* complex algorithm that tries to grab keys registered immediately after
|
||||
* the given key.
|
||||
*/
|
||||
public Object[] getBatchLoadableEntityIds(
|
||||
public Object [] getBatchLoadableEntityIds(
|
||||
final EntityMappingType entityDescriptor,
|
||||
final Object loadingId,
|
||||
final int maxBatchSize) {
|
||||
|
@ -328,6 +330,7 @@ public class BatchFetchQueue {
|
|||
batchLoadableCollections = CollectionHelper.mapOfSize( 12 );
|
||||
}
|
||||
|
||||
assert persister != null : "@AssumeAssertion(nullness)";
|
||||
final LinkedHashMap<CollectionEntry, PersistentCollection<?>> map =
|
||||
batchLoadableCollections.computeIfAbsent(
|
||||
persister.getRole(),
|
||||
|
@ -343,11 +346,13 @@ public class BatchFetchQueue {
|
|||
* if necessary
|
||||
*/
|
||||
public void removeBatchLoadableCollection(CollectionEntry ce) {
|
||||
final CollectionPersister persister = ce.getLoadedPersister();
|
||||
if ( batchLoadableCollections == null ) {
|
||||
return;
|
||||
}
|
||||
assert persister != null : "@AssumeAssertion(nullness)";
|
||||
LinkedHashMap<CollectionEntry, PersistentCollection<?>> map =
|
||||
batchLoadableCollections.get( ce.getLoadedPersister().getRole() );
|
||||
batchLoadableCollections.get( persister.getRole() );
|
||||
if ( map != null ) {
|
||||
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
|
||||
* creation of concretely typed array for ARRAY param binding to ensure
|
||||
* the driver does not need to cast/copy the values array.
|
||||
|
@ -363,7 +368,7 @@ public class BatchFetchQueue {
|
|||
public <T> void collectBatchLoadableCollectionKeys(
|
||||
int batchSize,
|
||||
IndexedConsumer<T> collector,
|
||||
T keyBeingLoaded,
|
||||
@NonNull T keyBeingLoaded,
|
||||
PluralAttributeMapping pluralAttributeMapping) {
|
||||
collector.accept( 0, keyBeingLoaded );
|
||||
|
||||
|
@ -383,9 +388,10 @@ public class BatchFetchQueue {
|
|||
|
||||
for ( Entry<CollectionEntry, PersistentCollection<?>> me : map.entrySet() ) {
|
||||
final CollectionEntry ce = me.getKey();
|
||||
final Object loadedKey = ce.getLoadedKey();
|
||||
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
|
||||
// (see for example Collections.processDereferencedCollection()
|
||||
// and CollectionEntry.afterAction())
|
||||
|
@ -407,21 +413,21 @@ public class BatchFetchQueue {
|
|||
|
||||
final boolean isEqual = pluralAttributeMapping.getKeyDescriptor().areEqual(
|
||||
keyBeingLoaded,
|
||||
ce.getLoadedKey(),
|
||||
loadedKey,
|
||||
context.getSession()
|
||||
);
|
||||
// final boolean isEqual = collectionPersister.getKeyType().isEqual(
|
||||
// id,
|
||||
// ce.getLoadedKey(),
|
||||
// loadedKey,
|
||||
// collectionPersister.getFactory()
|
||||
// );
|
||||
|
||||
if ( isEqual ) {
|
||||
end = i;
|
||||
}
|
||||
else if ( !isCached( ce.getLoadedKey(), pluralAttributeMapping.getCollectionDescriptor() ) ) {
|
||||
else if ( !isCached( loadedKey, pluralAttributeMapping.getCollectionDescriptor() ) ) {
|
||||
//noinspection unchecked
|
||||
collector.accept( i++, (T) ce.getLoadedKey() );
|
||||
collector.accept( i++, (T) loadedKey );
|
||||
}
|
||||
|
||||
if ( i == batchSize ) {
|
||||
|
@ -444,7 +450,7 @@ public class BatchFetchQueue {
|
|||
* @param batchSize the maximum number of keys to return
|
||||
* @return an array of collection keys, of length batchSize (padded with nulls)
|
||||
*/
|
||||
public Object[] getCollectionBatch(
|
||||
public Object [] getCollectionBatch(
|
||||
final CollectionPersister collectionPersister,
|
||||
final Object id,
|
||||
final int batchSize) {
|
||||
|
@ -465,9 +471,10 @@ public class BatchFetchQueue {
|
|||
if ( map != null ) {
|
||||
for ( Entry<CollectionEntry, PersistentCollection<?>> me : map.entrySet() ) {
|
||||
final CollectionEntry ce = me.getKey();
|
||||
final Object loadedKey = ce.getLoadedKey();
|
||||
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
|
||||
// (see for example Collections.processDereferencedCollection()
|
||||
// and CollectionEntry.afterAction())
|
||||
|
@ -488,7 +495,7 @@ public class BatchFetchQueue {
|
|||
|
||||
final boolean isEqual = collectionPersister.getKeyType().isEqual(
|
||||
id,
|
||||
ce.getLoadedKey(),
|
||||
loadedKey,
|
||||
collectionPersister.getFactory()
|
||||
);
|
||||
|
||||
|
@ -496,8 +503,8 @@ public class BatchFetchQueue {
|
|||
end = i;
|
||||
//checkForEnd = false;
|
||||
}
|
||||
else if ( !isCached( ce.getLoadedKey(), collectionPersister ) ) {
|
||||
keys[i++] = ce.getLoadedKey();
|
||||
else if ( !isCached( loadedKey, collectionPersister ) ) {
|
||||
keys[i++] = loadedKey;
|
||||
//count++;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.hibernate.collection.spi.AbstractPersistentCollection;
|
|||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.NullnessUtil;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
|
||||
|
@ -21,6 +22,9 @@ import java.io.ObjectOutputStream;
|
|||
import java.io.Serializable;
|
||||
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
|
||||
* of a collection with respect to its persistent state
|
||||
|
@ -33,14 +37,14 @@ public final class CollectionEntry implements Serializable {
|
|||
//ATTRIBUTES MAINTAINED BETWEEN FLUSH CYCLES
|
||||
|
||||
// session-start/post-flush persistent state
|
||||
private Serializable snapshot;
|
||||
private @Nullable Serializable snapshot;
|
||||
// allow the CollectionSnapshot to be serialized
|
||||
private String role;
|
||||
private @Nullable String role;
|
||||
|
||||
// "loaded" means the reference that is consistent
|
||||
// with the current database state
|
||||
private transient CollectionPersister loadedPersister;
|
||||
private Object loadedKey;
|
||||
private transient @Nullable CollectionPersister loadedPersister;
|
||||
private @Nullable Object loadedKey;
|
||||
|
||||
// ATTRIBUTES USED ONLY DURING FLUSH CYCLE
|
||||
|
||||
|
@ -56,8 +60,8 @@ public final class CollectionEntry implements Serializable {
|
|||
private transient boolean ignore;
|
||||
|
||||
// "current" means the reference that was found during flush()
|
||||
private transient CollectionPersister currentPersister;
|
||||
private transient Object currentKey;
|
||||
private transient @Nullable CollectionPersister currentPersister;
|
||||
private transient @Nullable Object currentKey;
|
||||
|
||||
/**
|
||||
* For newly wrapped collections, or dereferenced collection wrappers
|
||||
|
@ -88,7 +92,9 @@ public final class CollectionEntry implements Serializable {
|
|||
//collection.clearDirty()
|
||||
|
||||
this.loadedKey = loadedKey;
|
||||
setLoadedPersister( loadedPersister );
|
||||
|
||||
this.loadedPersister = loadedPersister;
|
||||
this.role = ( loadedPersister == null ? null : loadedPersister.getRole() );
|
||||
|
||||
collection.setSnapshot( loadedKey, role, null );
|
||||
|
||||
|
@ -106,7 +112,8 @@ public final class CollectionEntry implements Serializable {
|
|||
//collection.clearDirty()
|
||||
|
||||
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;
|
||||
|
||||
loadedKey = collection.getKey();
|
||||
setLoadedPersister(
|
||||
factory.getRuntimeMetamodels().getMappingMetamodel().getCollectionDescriptor( collection.getRole() )
|
||||
);
|
||||
loadedPersister = factory.getRuntimeMetamodels().getMappingMetamodel().getCollectionDescriptor( collection.getRole() );
|
||||
this.role = ( loadedPersister == null ? null : loadedPersister.getRole() );
|
||||
|
||||
snapshot = collection.getStoredSnapshot();
|
||||
}
|
||||
|
@ -132,10 +138,10 @@ public final class CollectionEntry implements Serializable {
|
|||
* @see #deserialize
|
||||
*/
|
||||
private CollectionEntry(
|
||||
String role,
|
||||
@Nullable String role,
|
||||
Serializable snapshot,
|
||||
Object loadedKey,
|
||||
SessionFactoryImplementor factory) {
|
||||
@Nullable SessionFactoryImplementor factory) {
|
||||
this.role = role;
|
||||
this.snapshot = snapshot;
|
||||
this.loadedKey = loadedKey;
|
||||
|
@ -176,7 +182,7 @@ public final class CollectionEntry implements Serializable {
|
|||
if ( nonMutableChange ) {
|
||||
throw new HibernateException(
|
||||
"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 {
|
||||
final CollectionPersister loadedPersister = getLoadedPersister();
|
||||
snapshot = loadedPersister.isMutable()
|
||||
snapshot = loadedPersister != null && loadedPersister.isMutable()
|
||||
? collection.getSnapshot( loadedPersister )
|
||||
: null;
|
||||
collection.setSnapshot( loadedKey, role, snapshot );
|
||||
final SharedSessionContractImplementor session = ((AbstractPersistentCollection<?>) collection).getSession();
|
||||
if ( session.getLoadQueryInfluencers().effectivelyBatchLoadable( loadedPersister ) ) {
|
||||
if ( loadedPersister != null && session.getLoadQueryInfluencers().effectivelyBatchLoadable( loadedPersister ) ) {
|
||||
session.getPersistenceContextInternal()
|
||||
.getBatchFetchQueue()
|
||||
.removeBatchLoadableCollection( this );
|
||||
|
@ -236,21 +242,21 @@ public final class CollectionEntry implements Serializable {
|
|||
if ( resnapshot ) {
|
||||
snapshot = loadedPersister == null || !loadedPersister.isMutable() ?
|
||||
null :
|
||||
collection.getSnapshot( loadedPersister ); //re-snapshot
|
||||
collection.getSnapshot( NullnessUtil.castNonNull( loadedPersister ) ); //re-snapshot
|
||||
}
|
||||
|
||||
collection.postAction();
|
||||
}
|
||||
|
||||
public Object getKey() {
|
||||
public @Nullable Object getKey() {
|
||||
return getLoadedKey();
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
public @Nullable String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public Serializable getSnapshot() {
|
||||
public @Nullable Serializable getSnapshot() {
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
|
@ -275,17 +281,17 @@ public final class CollectionEntry implements Serializable {
|
|||
fromMerge = true;
|
||||
}
|
||||
|
||||
private void setLoadedPersister(CollectionPersister persister) {
|
||||
private void setLoadedPersister(@Nullable CollectionPersister persister) {
|
||||
loadedPersister = persister;
|
||||
setRole( persister == null ? null : persister.getRole() );
|
||||
}
|
||||
|
||||
void afterDeserialize(SessionFactoryImplementor factory) {
|
||||
void afterDeserialize(@Nullable SessionFactoryImplementor factory) {
|
||||
if ( factory == null ) {
|
||||
loadedPersister = null;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
public CollectionPersister getCurrentPersister() {
|
||||
public @Nullable CollectionPersister getCurrentPersister() {
|
||||
return currentPersister;
|
||||
}
|
||||
|
||||
public void setCurrentPersister(CollectionPersister currentPersister) {
|
||||
public void setCurrentPersister(@Nullable CollectionPersister currentPersister) {
|
||||
this.currentPersister = currentPersister;
|
||||
}
|
||||
|
||||
|
@ -349,26 +355,26 @@ public final class CollectionEntry implements Serializable {
|
|||
* This is only available late during the flush
|
||||
* cycle
|
||||
*/
|
||||
public Object getCurrentKey() {
|
||||
public @Nullable Object getCurrentKey() {
|
||||
return currentKey;
|
||||
}
|
||||
|
||||
public void setCurrentKey(Object currentKey) {
|
||||
public void setCurrentKey(@Nullable Object currentKey) {
|
||||
this.currentKey = currentKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is only available late during the flush cycle
|
||||
*/
|
||||
public CollectionPersister getLoadedPersister() {
|
||||
public @Nullable CollectionPersister getLoadedPersister() {
|
||||
return loadedPersister;
|
||||
}
|
||||
|
||||
public Object getLoadedKey() {
|
||||
public @Nullable Object getLoadedKey() {
|
||||
return loadedKey;
|
||||
}
|
||||
|
||||
public void setRole(String role) {
|
||||
public void setRole(@Nullable String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
|
@ -398,9 +404,10 @@ public final class CollectionEntry implements Serializable {
|
|||
// does the collection already have
|
||||
// it's own up-to-date snapshot?
|
||||
final CollectionPersister loadedPersister = getLoadedPersister();
|
||||
Serializable snapshot = getSnapshot();
|
||||
return collection.wasInitialized() &&
|
||||
( loadedPersister ==null || loadedPersister.isMutable() ) &&
|
||||
collection.isSnapshotEmpty( getSnapshot() );
|
||||
( loadedPersister == null || loadedPersister.isMutable() ) &&
|
||||
(snapshot != null ? collection.isSnapshotEmpty( snapshot ) : true);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ import org.hibernate.persister.collection.CollectionPersister;
|
|||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Uniquely identifies a collection instance in a particular session.
|
||||
*
|
||||
|
@ -39,7 +41,7 @@ public final class CollectionKey implements Serializable {
|
|||
|
||||
private CollectionKey(
|
||||
String role,
|
||||
Object key,
|
||||
@Nullable Object key,
|
||||
Type keyType,
|
||||
SessionFactoryImplementor factory) {
|
||||
this.role = role;
|
||||
|
@ -77,7 +79,7 @@ public final class CollectionKey implements Serializable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object other) {
|
||||
public boolean equals(final @Nullable Object other) {
|
||||
if ( this == other ) {
|
||||
return true;
|
||||
}
|
||||
|
@ -127,7 +129,8 @@ public final class CollectionKey implements Serializable {
|
|||
(String) ois.readObject(),
|
||||
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.spi.AppliedGraph;
|
||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||
import org.hibernate.internal.util.NullnessUtil;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Think of this as the composite modeling of a graph
|
||||
* and the semantic.
|
||||
|
@ -33,8 +36,8 @@ public class EffectiveEntityGraph implements AppliedGraph, Serializable {
|
|||
|
||||
private final boolean allowOverwrite;
|
||||
|
||||
private GraphSemantic semantic;
|
||||
private RootGraphImplementor<?> graph;
|
||||
private @Nullable GraphSemantic semantic;
|
||||
private @Nullable RootGraphImplementor<?> graph;
|
||||
|
||||
/**
|
||||
* @implSpec I explicitly made this constructor package protected
|
||||
|
@ -59,12 +62,12 @@ public class EffectiveEntityGraph implements AppliedGraph, Serializable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public GraphSemantic getSemantic() {
|
||||
public @Nullable GraphSemantic getSemantic() {
|
||||
return semantic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RootGraphImplementor<?> getGraph() {
|
||||
public @Nullable RootGraphImplementor<?> getGraph() {
|
||||
return graph;
|
||||
}
|
||||
|
||||
|
@ -75,7 +78,7 @@ public class EffectiveEntityGraph implements AppliedGraph, Serializable {
|
|||
* @throws IllegalArgumentException Thrown if the semantic is null
|
||||
* @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 ) {
|
||||
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 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() ) {
|
||||
return;
|
||||
}
|
||||
|
@ -138,6 +141,7 @@ public class EffectiveEntityGraph implements AppliedGraph, Serializable {
|
|||
applyGraph( fetchHint, GraphSemantic.FETCH );
|
||||
}
|
||||
else {
|
||||
assert loadHint != null : "@AssumeAssertion(nullness)";
|
||||
applyGraph( loadHint, GraphSemantic.LOAD );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ import org.hibernate.AssertionFailure;
|
|||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -44,7 +46,7 @@ public final class EntityKey implements Serializable {
|
|||
* @param id The entity id
|
||||
* @param persister The entity persister
|
||||
*/
|
||||
public EntityKey(Object id, EntityPersister persister) {
|
||||
public EntityKey(@Nullable Object id, EntityPersister persister) {
|
||||
this.persister = persister;
|
||||
if ( id == null ) {
|
||||
throw new AssertionFailure( "null identifier (" + persister.getEntityName() + ")" );
|
||||
|
@ -82,7 +84,7 @@ public final class EntityKey implements Serializable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if ( this == other ) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,10 @@ import java.io.Serializable;
|
|||
import org.hibernate.pretty.MessageHelper;
|
||||
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
|
||||
* by some unique property reference, as opposed to identifier.
|
||||
|
@ -41,7 +45,7 @@ public class EntityUniqueKey implements Serializable {
|
|||
this.entityName = entityName;
|
||||
this.key = key;
|
||||
this.keyType = keyType;
|
||||
this.hashCode = generateHashCode( factory );
|
||||
this.hashCode = generateHashCode( entityName, uniqueKeyName, keyType, key, factory );
|
||||
}
|
||||
|
||||
public String getEntityName() {
|
||||
|
@ -56,7 +60,7 @@ public class EntityUniqueKey implements Serializable {
|
|||
return uniqueKeyName;
|
||||
}
|
||||
|
||||
public int generateHashCode(SessionFactoryImplementor factory) {
|
||||
public static int generateHashCode(String entityName, String uniqueKeyName, Type keyType, Object key, SessionFactoryImplementor factory) {
|
||||
int result = 17;
|
||||
result = 37 * result + entityName.hashCode();
|
||||
result = 37 * result + uniqueKeyName.hashCode();
|
||||
|
@ -70,7 +74,10 @@ public class EntityUniqueKey implements Serializable {
|
|||
}
|
||||
|
||||
@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;
|
||||
return that != null && that.entityName.equals( entityName )
|
||||
&& that.uniqueKeyName.equals( uniqueKeyName )
|
||||
|
|
|
@ -22,6 +22,8 @@ import org.hibernate.action.spi.Executable;
|
|||
import org.hibernate.event.spi.EventSource;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* A list of {@link Executable executeble actions}. Responsible for
|
||||
* {@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 Sorter<E> sorter;
|
||||
private final @Nullable Sorter<E> sorter;
|
||||
private final boolean requiresSorting;
|
||||
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
|
||||
* 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.
|
||||
|
@ -296,9 +298,10 @@ public class ExecutableList<E extends ComparableExecutable>
|
|||
oos.writeInt( -1 );
|
||||
}
|
||||
else {
|
||||
final Set<Serializable> qs = querySpaces;
|
||||
oos.writeInt( querySpaces.size() );
|
||||
// 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() );
|
||||
}
|
||||
}
|
||||
|
@ -329,10 +332,12 @@ public class ExecutableList<E extends ComparableExecutable>
|
|||
this.querySpaces = null;
|
||||
}
|
||||
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++ ) {
|
||||
querySpaces.add( in.readUTF() );
|
||||
}
|
||||
this.querySpaces = querySpaces;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ package org.hibernate.engine.spi;
|
|||
|
||||
import org.hibernate.annotations.ResultCheckStyle;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* For persistence operations (INSERT, UPDATE, DELETE) what style of
|
||||
* determining results (success/failure) is to be used.
|
||||
|
@ -54,7 +56,7 @@ public enum ExecuteUpdateResultCheckStyle {
|
|||
return name;
|
||||
}
|
||||
|
||||
public static ExecuteUpdateResultCheckStyle fromResultCheckStyle(ResultCheckStyle style) {
|
||||
public static @Nullable ExecuteUpdateResultCheckStyle fromResultCheckStyle(ResultCheckStyle style) {
|
||||
switch (style) {
|
||||
case 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 ) ) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import java.util.Set;
|
|||
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Represents the definition of a {@link org.hibernate.Filter filter}.
|
||||
* 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.
|
||||
*/
|
||||
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.defaultFilterCondition = defaultCondition;
|
||||
if ( explicitParamJaMappings != null ) {
|
||||
|
@ -59,7 +61,9 @@ public class FilterDefinition implements Serializable {
|
|||
* @return The parameters named by this configuration.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
public JdbcMapping getParameterJdbcMapping(String parameterName) {
|
||||
public @Nullable JdbcMapping getParameterJdbcMapping(String parameterName) {
|
||||
return explicitParamJaMappings.get( parameterName );
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@ import org.hibernate.internal.CoreLogging;
|
|||
|
||||
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 new transient instance or a previously persistent transient instance.
|
||||
|
@ -23,7 +25,7 @@ import org.jboss.logging.Logger;
|
|||
public class IdentifierValue implements UnsavedValueStrategy {
|
||||
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
|
||||
|
@ -73,13 +75,13 @@ public class IdentifierValue implements UnsavedValueStrategy {
|
|||
*/
|
||||
public static final IdentifierValue NULL = new IdentifierValue() {
|
||||
@Override
|
||||
public Boolean isUnsaved(Object id) {
|
||||
public Boolean isUnsaved(@Nullable Object id) {
|
||||
LOG.trace( "ID unsaved-value strategy NULL" );
|
||||
return id == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable getDefaultValue(Object currentValue) {
|
||||
public @Nullable Serializable getDefaultValue(Object currentValue) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -94,13 +96,13 @@ public class IdentifierValue implements UnsavedValueStrategy {
|
|||
*/
|
||||
public static final IdentifierValue UNDEFINED = new IdentifierValue() {
|
||||
@Override
|
||||
public Boolean isUnsaved(Object id) {
|
||||
public @Nullable Boolean isUnsaved(Object id) {
|
||||
LOG.trace( "ID unsaved-value strategy UNDEFINED" );
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable getDefaultValue(Object currentValue) {
|
||||
public @Nullable Serializable getDefaultValue(Object currentValue) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -126,13 +128,13 @@ public class IdentifierValue implements UnsavedValueStrategy {
|
|||
* Does the given identifier belong to a new instance?
|
||||
*/
|
||||
@Override
|
||||
public Boolean isUnsaved(Object id) {
|
||||
public @Nullable Boolean isUnsaved(@Nullable Object id) {
|
||||
LOG.tracev( "ID unsaved-value: {0}", value );
|
||||
return id == null || id.equals( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDefaultValue(Object currentValue) {
|
||||
public @Nullable Object getDefaultValue(@Nullable Object currentValue) {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,10 +23,13 @@ import org.hibernate.graph.GraphSemantic;
|
|||
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||
import org.hibernate.internal.FilterImpl;
|
||||
import org.hibernate.internal.SessionCreationOptions;
|
||||
import org.hibernate.internal.util.NullnessUtil;
|
||||
import org.hibernate.loader.ast.spi.CascadingFetchProfile;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import static java.util.Collections.emptySet;
|
||||
import static org.hibernate.engine.FetchStyle.SUBSELECT;
|
||||
|
||||
|
@ -51,7 +54,7 @@ public class LoadQueryInfluencers implements Serializable {
|
|||
@Deprecated(forRemoval = true)
|
||||
public static final LoadQueryInfluencers NONE = new LoadQueryInfluencers();
|
||||
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
private final @Nullable SessionFactoryImplementor sessionFactory;
|
||||
|
||||
private CascadingFetchProfile enabledCascadingFetchProfile;
|
||||
|
||||
|
@ -85,7 +88,7 @@ public class LoadQueryInfluencers implements Serializable {
|
|||
subselectFetchEnabled = options.isSubselectFetchEnabled();
|
||||
}
|
||||
|
||||
public EffectiveEntityGraph applyEntityGraph(RootGraphImplementor<?> rootGraph, GraphSemantic graphSemantic) {
|
||||
public EffectiveEntityGraph applyEntityGraph(@Nullable RootGraphImplementor<?> rootGraph, @Nullable GraphSemantic graphSemantic) {
|
||||
final EffectiveEntityGraph effectiveEntityGraph = getEffectiveEntityGraph();
|
||||
if ( graphSemantic != null ) {
|
||||
if ( rootGraph == null ) {
|
||||
|
@ -96,7 +99,7 @@ public class LoadQueryInfluencers implements Serializable {
|
|||
return effectiveEntityGraph;
|
||||
}
|
||||
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
public @Nullable SessionFactoryImplementor getSessionFactory() {
|
||||
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 ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -197,7 +200,7 @@ public class LoadQueryInfluencers implements Serializable {
|
|||
|
||||
public Filter enableFilter(String filterName) {
|
||||
checkMutability();
|
||||
FilterImpl filter = new FilterImpl( sessionFactory.getFilterDefinition( filterName ) );
|
||||
FilterImpl filter = new FilterImpl( NullnessUtil.castNonNull( sessionFactory ).getFilterDefinition( filterName ) );
|
||||
if ( enabledFilters == null ) {
|
||||
this.enabledFilters = new HashMap<>();
|
||||
}
|
||||
|
@ -223,7 +226,7 @@ public class LoadQueryInfluencers implements Serializable {
|
|||
return filter.getParameter( parsed[1] );
|
||||
}
|
||||
|
||||
public static String[] parseFilterParameterName(String filterParameterName) {
|
||||
public static String [] parseFilterParameterName(String filterParameterName) {
|
||||
int dot = filterParameterName.lastIndexOf( '.' );
|
||||
if ( dot <= 0 ) {
|
||||
throw new IllegalArgumentException(
|
||||
|
@ -274,7 +277,7 @@ public class LoadQueryInfluencers implements Serializable {
|
|||
}
|
||||
|
||||
@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 =
|
||||
hasEnabledFetchProfiles() ? new HashSet<>( enabledFetchProfileNames ) : null;
|
||||
if ( disabledFetchProfiles != null && enabledFetchProfileNames != null ) {
|
||||
|
@ -353,7 +356,7 @@ public class LoadQueryInfluencers implements Serializable {
|
|||
private boolean isSubselectFetchEnabledInProfile(CollectionPersister persister) {
|
||||
if ( hasEnabledFetchProfiles() ) {
|
||||
for ( String profile : getEnabledFetchProfileNames() ) {
|
||||
final FetchProfile fetchProfile = sessionFactory.getFetchProfile( profile );
|
||||
final FetchProfile fetchProfile = persister.getFactory().getFetchProfile( profile ) ;
|
||||
if ( fetchProfile != null ) {
|
||||
final Fetch fetch = fetchProfile.getFetchByRole( persister.getRole() );
|
||||
if ( fetch != null && fetch.getMethod() == SUBSELECT) {
|
||||
|
@ -382,7 +385,7 @@ public class LoadQueryInfluencers implements Serializable {
|
|||
private boolean hasSubselectLoadableCollectionsEnabledInProfile(EntityPersister persister) {
|
||||
if ( hasEnabledFetchProfiles() ) {
|
||||
for ( String profile : getEnabledFetchProfileNames() ) {
|
||||
if ( sessionFactory.getFetchProfile( profile )
|
||||
if ( persister.getFactory().getFetchProfile( profile )
|
||||
.hasSubselectLoadableCollectionsEnabled( persister ) ) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ import org.hibernate.engine.internal.ManagedTypeHelper;
|
|||
import org.hibernate.proxy.HibernateProxy;
|
||||
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}.
|
||||
*
|
||||
|
@ -22,46 +24,46 @@ import org.hibernate.proxy.ProxyConfiguration;
|
|||
@Internal
|
||||
public interface PrimeAmongSecondarySupertypes {
|
||||
|
||||
default ManagedEntity asManagedEntity() {
|
||||
default @Nullable ManagedEntity asManagedEntity() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default PersistentAttributeInterceptable asPersistentAttributeInterceptable() {
|
||||
default @Nullable PersistentAttributeInterceptable asPersistentAttributeInterceptable() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default SelfDirtinessTracker asSelfDirtinessTracker() {
|
||||
default @Nullable SelfDirtinessTracker asSelfDirtinessTracker() {
|
||||
return null;
|
||||
}
|
||||
|
||||
//Included for consistency but doesn't seem to be used?
|
||||
default Managed asManaged() {
|
||||
default @Nullable Managed asManaged() {
|
||||
return null;
|
||||
}
|
||||
|
||||
//Included for consistency but doesn't seem to be used?
|
||||
default ManagedComposite asManagedComposite() {
|
||||
default @Nullable ManagedComposite asManagedComposite() {
|
||||
return null;
|
||||
}
|
||||
|
||||
//Included for consistency but doesn't seem to be used?
|
||||
default ManagedMappedSuperclass asManagedMappedSuperclass() {
|
||||
default @Nullable ManagedMappedSuperclass asManagedMappedSuperclass() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default CompositeOwner asCompositeOwner() {
|
||||
default @Nullable CompositeOwner asCompositeOwner() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default CompositeTracker asCompositeTracker() {
|
||||
default @Nullable CompositeTracker asCompositeTracker() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default HibernateProxy asHibernateProxy() {
|
||||
default @Nullable HibernateProxy asHibernateProxy() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default ProxyConfiguration asProxyConfiguration() {
|
||||
default @Nullable ProxyConfiguration asProxyConfiguration() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ import jakarta.persistence.criteria.CriteriaDelete;
|
|||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.CriteriaUpdate;
|
||||
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
|
||||
|
@ -165,7 +166,7 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
|
|||
}
|
||||
|
||||
@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 );
|
||||
}
|
||||
|
||||
|
@ -853,22 +854,22 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
|
|||
}
|
||||
|
||||
@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 );
|
||||
}
|
||||
|
||||
@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 );
|
||||
}
|
||||
|
||||
@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 );
|
||||
}
|
||||
|
||||
@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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ import jakarta.persistence.criteria.CriteriaDelete;
|
|||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.CriteriaUpdate;
|
||||
import jakarta.persistence.metamodel.Metamodel;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* This helper class allows decorating a Session instance, while the
|
||||
|
@ -809,22 +810,22 @@ public class SessionLazyDelegator implements Session {
|
|||
}
|
||||
|
||||
@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 );
|
||||
}
|
||||
|
||||
@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 );
|
||||
}
|
||||
|
||||
@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 );
|
||||
}
|
||||
|
||||
@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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.Set;
|
|||
import java.util.UUID;
|
||||
import jakarta.persistence.FlushModeType;
|
||||
import jakarta.persistence.TransactionRequiredException;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.FlushMode;
|
||||
|
@ -307,7 +308,7 @@ public interface SharedSessionContractImplementor
|
|||
* @param entityName optional entity name
|
||||
* @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},
|
||||
|
|
|
@ -11,6 +11,8 @@ import jakarta.persistence.FlushModeType;
|
|||
import jakarta.persistence.criteria.CriteriaDelete;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.CriteriaUpdate;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -413,7 +415,7 @@ public class SharedSessionDelegatorBaseImpl implements SharedSessionContractImpl
|
|||
}
|
||||
|
||||
@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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ import java.io.Serializable;
|
|||
import org.hibernate.internal.util.ValueHolder;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
initTransients();
|
||||
this.hashcode = hashCode(type, value);
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
|
@ -47,7 +49,7 @@ public final class TypedValue implements Serializable {
|
|||
return hashcode.getValue();
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if ( this == other ) {
|
||||
return true;
|
||||
}
|
||||
|
@ -62,10 +64,10 @@ public final class TypedValue implements Serializable {
|
|||
private void readObject(ObjectInputStream ois)
|
||||
throws ClassNotFoundException, IOException {
|
||||
ois.defaultReadObject();
|
||||
initTransients();
|
||||
this.hashcode = hashCode(type, value);
|
||||
}
|
||||
|
||||
private void initTransients() {
|
||||
this.hashcode = new ValueHolder<>( () -> value == null ? 0 : type.getHashCode( value ) );
|
||||
private static ValueHolder hashCode(Type type, Object value) {
|
||||
return new ValueHolder<>( () -> value == null ? 0 : type.getHashCode( value ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
*/
|
||||
package org.hibernate.engine.spi;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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.
|
||||
|
@ -30,5 +32,5 @@ public interface UnsavedValueStrategy {
|
|||
*
|
||||
* @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.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* A strategy for determining if a version value is a version of
|
||||
* a new transient instance or a previously persistent transient instance.
|
||||
|
@ -23,20 +25,20 @@ import org.jboss.logging.Logger;
|
|||
public class VersionValue implements UnsavedValueStrategy {
|
||||
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
|
||||
* is null, otherwise assume it is a detached instance.
|
||||
*/
|
||||
public static final VersionValue NULL = new VersionValue() {
|
||||
@Override
|
||||
public Boolean isUnsaved(Object version) {
|
||||
public Boolean isUnsaved(@Nullable Object version) {
|
||||
LOG.trace( "Version unsaved-value strategy NULL" );
|
||||
return version == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDefaultValue(Object currentValue) {
|
||||
public @Nullable Object getDefaultValue(Object currentValue) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -52,7 +54,7 @@ public class VersionValue implements UnsavedValueStrategy {
|
|||
*/
|
||||
public static final VersionValue UNDEFINED = new VersionValue() {
|
||||
@Override
|
||||
public Boolean isUnsaved(Object version) {
|
||||
public @Nullable Boolean isUnsaved(@Nullable Object version) {
|
||||
LOG.trace( "Version unsaved-value strategy UNDEFINED" );
|
||||
return version == null ? Boolean.TRUE : null;
|
||||
}
|
||||
|
@ -75,7 +77,7 @@ public class VersionValue implements UnsavedValueStrategy {
|
|||
public static final VersionValue NEGATIVE = new VersionValue() {
|
||||
|
||||
@Override
|
||||
public Boolean isUnsaved(Object version) throws MappingException {
|
||||
public Boolean isUnsaved(@Nullable Object version) throws MappingException {
|
||||
LOG.trace( "Version unsaved-value strategy NEGATIVE" );
|
||||
if ( version == null ) {
|
||||
return Boolean.TRUE;
|
||||
|
@ -114,13 +116,13 @@ public class VersionValue implements UnsavedValueStrategy {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Boolean isUnsaved(Object version) throws MappingException {
|
||||
public @Nullable Boolean isUnsaved(@Nullable Object version) throws MappingException {
|
||||
LOG.tracev( "Version unsaved-value: {0}", value );
|
||||
return version == null || version.equals( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDefaultValue(Object currentValue) {
|
||||
public @Nullable Object getDefaultValue(@Nullable Object currentValue) {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ package org.hibernate.graph.spi;
|
|||
|
||||
import org.hibernate.graph.GraphSemantic;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Contract for anything a fetch/load graph can be applied
|
||||
*
|
||||
|
@ -17,10 +19,10 @@ public interface AppliedGraph {
|
|||
/**
|
||||
* The applied graph
|
||||
*/
|
||||
RootGraphImplementor<?> getGraph();
|
||||
@Nullable RootGraphImplementor<?> getGraph();
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
public static String join(String seperator, String[] strings) {
|
||||
public static String join(String separator, String[] strings) {
|
||||
int length = strings.length;
|
||||
if ( length == 0 ) {
|
||||
return "";
|
||||
|
@ -54,7 +54,7 @@ public final class StringHelper {
|
|||
StringBuilder buf = new StringBuilder( length * firstStringLength )
|
||||
.append( strings[0] );
|
||||
for ( int i = 1; i < length; i++ ) {
|
||||
buf.append( seperator ).append( strings[i] );
|
||||
buf.append( separator ).append( strings[i] );
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ import org.hibernate.sql.results.graph.DomainResult;
|
|||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
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
|
||||
* application's domain model: an attribute, an entity identifier,
|
||||
|
@ -200,7 +202,7 @@ public interface ModelPart extends MappingModelExpressible {
|
|||
|
||||
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)
|
||||
return Objects.deepEquals( one, other );
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.util.Set;
|
|||
|
||||
import jakarta.persistence.CacheRetrieveMode;
|
||||
import jakarta.persistence.CacheStoreMode;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.LockOptions;
|
||||
|
@ -248,12 +249,12 @@ public class QueryOptionsImpl implements MutableQueryOptions, AppliedGraph {
|
|||
}
|
||||
|
||||
@Override
|
||||
public RootGraphImplementor<?> getGraph() {
|
||||
public @Nullable RootGraphImplementor<?> getGraph() {
|
||||
return rootGraph;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphSemantic getSemantic() {
|
||||
public @Nullable GraphSemantic getSemantic() {
|
||||
return graphSemantic;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue