HHH-16515 - Add o.h.property.access.spi to nullness checking

HHH-16515 - Add o.h.property.access.internal to nullness checking

Signed-off-by: Jan Schatteman <jschatte@redhat.com>
This commit is contained in:
Jan Schatteman 2023-07-05 18:48:15 +02:00 committed by Christian Beikov
parent 22091b2254
commit 58c10758e0
31 changed files with 163 additions and 111 deletions

View File

@ -5,5 +5,10 @@ package java.lang.reflect;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
public final class Method extends Executable { public final class Method extends Executable {
void invoke(@Nullable Object obj, Object @Nullable ... args); void invoke(@Nullable Object obj, @Nullable Object @Nullable ... args);
}
public final
class Field extends AccessibleObject implements Member {
public void set(Object obj, @Nullable Object value);
} }

View File

@ -544,7 +544,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|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|transaction)|(action|context|bytecode)\\.spi)\\.'
] ]
} }

View File

@ -8,6 +8,8 @@ package org.hibernate;
import static org.hibernate.internal.util.StringHelper.qualify; import static org.hibernate.internal.util.StringHelper.qualify;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* A problem occurred accessing a property of an instance of a * A problem occurred accessing a property of an instance of a
* persistent class by reflection, or via enhanced entities. * persistent class by reflection, or via enhanced entities.
@ -38,7 +40,7 @@ public class PropertyAccessException extends HibernateException {
* @param propertyName The name of the property. * @param propertyName The name of the property.
*/ */
public PropertyAccessException( public PropertyAccessException(
Throwable cause, @Nullable Throwable cause,
String message, String message,
boolean wasSetter, boolean wasSetter,
Class<?> persistentClass, Class<?> persistentClass,

View File

@ -8,6 +8,8 @@ package org.hibernate;
import java.util.Collection; import java.util.Collection;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@ -28,7 +30,7 @@ public class PropertySetterAccessException extends PropertyAccessException {
String propertyName, String propertyName,
Class<?> expectedType, Class<?> expectedType,
Object target, Object target,
Object value) { @Nullable Object value) {
super( super(
cause, cause,
String.format( String.format(

View File

@ -19,6 +19,8 @@ import org.hibernate.proxy.HibernateProxy;
import java.util.Objects; import java.util.Objects;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* This is a helper to encapsulate an optimal strategy to execute type checks * This is a helper to encapsulate an optimal strategy to execute type checks
* for interfaces which attempts to avoid the performance issues tracked * for interfaces which attempts to avoid the performance issues tracked
@ -158,7 +160,7 @@ public final class ManagedTypeHelper {
* @param entity * @param entity
* @return true if and only if the entity implements {@see CompositeTracker} * @return true if and only if the entity implements {@see CompositeTracker}
*/ */
public static boolean isCompositeTracker(final Object entity) { public static boolean isCompositeTracker(final @Nullable Object entity) {
if ( entity instanceof PrimeAmongSecondarySupertypes ) { if ( entity instanceof PrimeAmongSecondarySupertypes ) {
PrimeAmongSecondarySupertypes t = (PrimeAmongSecondarySupertypes) entity; PrimeAmongSecondarySupertypes t = (PrimeAmongSecondarySupertypes) entity;
return t.asCompositeTracker() != null; return t.asCompositeTracker() != null;

View File

@ -44,6 +44,7 @@ import org.jboss.logging.annotations.ValidIdRange;
import jakarta.transaction.Synchronization; import jakarta.transaction.Synchronization;
import jakarta.transaction.SystemException; import jakarta.transaction.SystemException;
import org.checkerframework.checker.nullness.qual.Nullable;
import static org.jboss.logging.Logger.Level.DEBUG; import static org.jboss.logging.Logger.Level.DEBUG;
import static org.jboss.logging.Logger.Level.ERROR; import static org.jboss.logging.Logger.Level.ERROR;
@ -278,7 +279,7 @@ public interface CoreMessageLogger extends BasicLogger {
@LogMessage(level = ERROR) @LogMessage(level = ERROR)
@Message(value = "Expected type: %s, actual value: %s", id = 91) @Message(value = "Expected type: %s, actual value: %s", id = 91)
void expectedType(String name, void expectedType(String name,
String string); @Nullable String string);
@LogMessage(level = WARN) @LogMessage(level = WARN)
@Message(value = "An item was expired by the cache while it was locked (increase your cache timeout): %s", id = 92) @Message(value = "An item was expired by the cache while it was locked (increase your cache timeout): %s", id = 92)

View File

@ -19,10 +19,13 @@ import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInter
import org.hibernate.engine.spi.CompositeOwner; import org.hibernate.engine.spi.CompositeOwner;
import org.hibernate.engine.spi.CompositeTracker; import org.hibernate.engine.spi.CompositeTracker;
import org.hibernate.engine.spi.PersistentAttributeInterceptor; import org.hibernate.engine.spi.PersistentAttributeInterceptor;
import org.hibernate.internal.util.NullnessHelper;
import org.hibernate.internal.util.NullnessUtil;
import jakarta.persistence.Access; import jakarta.persistence.Access;
import jakarta.persistence.AccessType; import jakarta.persistence.AccessType;
import jakarta.persistence.Transient; import jakarta.persistence.Transient;
import org.checkerframework.checker.nullness.qual.Nullable;
import static org.hibernate.engine.internal.ManagedTypeHelper.asCompositeOwner; import static org.hibernate.engine.internal.ManagedTypeHelper.asCompositeOwner;
import static org.hibernate.engine.internal.ManagedTypeHelper.asCompositeTracker; import static org.hibernate.engine.internal.ManagedTypeHelper.asCompositeTracker;
@ -41,7 +44,7 @@ public class AccessStrategyHelper {
public static final int COMPOSITE_OWNER = 2; public static final int COMPOSITE_OWNER = 2;
public static final int PERSISTENT_ATTRIBUTE_INTERCEPTABLE_MASK = 4; public static final int PERSISTENT_ATTRIBUTE_INTERCEPTABLE_MASK = 4;
public static Field fieldOrNull(Class<?> containerJavaType, String propertyName) { public static @Nullable Field fieldOrNull(Class<?> containerJavaType, String propertyName) {
try { try {
return findField( containerJavaType, propertyName ); return findField( containerJavaType, propertyName );
} }
@ -67,7 +70,7 @@ public class AccessStrategyHelper {
return field != null ? AccessType.FIELD : AccessType.PROPERTY; return field != null ? AccessType.FIELD : AccessType.PROPERTY;
} }
public static AccessType getExplicitAccessType(Class<?> containerClass, String propertyName, Field field) { public static @Nullable AccessType getExplicitAccessType(Class<?> containerClass, String propertyName, @Nullable Field field) {
if ( isRecord( containerClass ) ) { if ( isRecord( containerClass ) ) {
try { try {
containerClass.getMethod( propertyName, NO_PARAM_SIGNATURE ); containerClass.getMethod( propertyName, NO_PARAM_SIGNATURE );
@ -160,7 +163,7 @@ public class AccessStrategyHelper {
} }
} }
public static Method findIsMethodVariant(Class<?> containerClass, String stemName) { public static @Nullable Method findIsMethodVariant(Class<?> containerClass, String stemName) {
// verify that the Class does not also define a method with the same stem name with 'is' // verify that the Class does not also define a method with the same stem name with 'is'
try { try {
final Method isMethod = containerClass.getDeclaredMethod( "is" + stemName ); final Method isMethod = containerClass.getDeclaredMethod( "is" + stemName );
@ -174,7 +177,7 @@ public class AccessStrategyHelper {
return null; return null;
} }
protected static AccessType getAccessTypeOrNull(AnnotatedElement element) { protected static @Nullable AccessType getAccessTypeOrNull(@Nullable AnnotatedElement element) {
if ( element == null ) { if ( element == null ) {
return null; return null;
} }
@ -188,13 +191,13 @@ public class AccessStrategyHelper {
| ( isPersistentAttributeInterceptableType( containerClass ) ? AccessStrategyHelper.PERSISTENT_ATTRIBUTE_INTERCEPTABLE_MASK : 0 ); | ( isPersistentAttributeInterceptableType( containerClass ) ? AccessStrategyHelper.PERSISTENT_ATTRIBUTE_INTERCEPTABLE_MASK : 0 );
} }
public static void handleEnhancedInjection(Object target, Object value, int enhancementState, String propertyName) { public static void handleEnhancedInjection(Object target, @Nullable Object value, int enhancementState, String propertyName) {
// This sets the component relation for dirty tracking purposes // This sets the component relation for dirty tracking purposes
if ( ( enhancementState & COMPOSITE_OWNER ) != 0 if ( ( enhancementState & COMPOSITE_OWNER ) != 0
&& ( ( enhancementState & COMPOSITE_TRACKER_MASK ) != 0 && ( ( enhancementState & COMPOSITE_TRACKER_MASK ) != 0
&& value != null && value != null
|| isCompositeTracker( value ) ) ) { || isCompositeTracker( value ) ) ) {
asCompositeTracker( value ).$$_hibernate_setOwner( propertyName, asCompositeOwner( target ) ); asCompositeTracker( NullnessUtil.castNonNull(value) ).$$_hibernate_setOwner( propertyName, asCompositeOwner( target ) );
} }
// This marks the attribute as initialized, so it doesn't get lazily loaded afterward // This marks the attribute as initialized, so it doesn't get lazily loaded afterward

View File

@ -12,11 +12,14 @@ import java.lang.reflect.Type;
import java.util.Map; import java.util.Map;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.NullnessUtil;
import org.hibernate.property.access.spi.Getter; import org.hibernate.property.access.spi.Getter;
import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.property.access.spi.PropertyAccessStrategy; import org.hibernate.property.access.spi.PropertyAccessStrategy;
import org.hibernate.property.access.spi.Setter; import org.hibernate.property.access.spi.Setter;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* @author Christian Beikov * @author Christian Beikov
*/ */
@ -44,24 +47,26 @@ public class ChainedPropertyAccessImpl implements PropertyAccess, Getter, Setter
} }
@Override @Override
public Object get(Object owner) { public @Nullable Object get(Object owner) {
@Nullable Object result = owner;
for ( int i = 0; i < propertyAccesses.length; i++ ) { for ( int i = 0; i < propertyAccesses.length; i++ ) {
owner = propertyAccesses[i].getGetter().get( owner ); result = propertyAccesses[i].getGetter().get( NullnessUtil.castNonNull( result ) );
} }
return owner; return result;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) { public @Nullable Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) {
@Nullable Object result = owner;
for ( int i = 0; i < propertyAccesses.length; i++ ) { for ( int i = 0; i < propertyAccesses.length; i++ ) {
owner = propertyAccesses[i].getGetter().getForInsert( owner, mergeMap, session ); result = propertyAccesses[i].getGetter().getForInsert( NullnessUtil.castNonNull( result ), mergeMap, session );
} }
return owner; return result;
} }
@Override @Override
public void set(Object target, Object value) { public void set(Object target, @Nullable Object value) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@ -76,17 +81,17 @@ public class ChainedPropertyAccessImpl implements PropertyAccess, Getter, Setter
} }
@Override @Override
public Member getMember() { public @Nullable Member getMember() {
return null; return null;
} }
@Override @Override
public String getMethodName() { public @Nullable String getMethodName() {
return null; return null;
} }
@Override @Override
public Method getMethod() { public @Nullable Method getMethod() {
return null; return null;
} }
} }

View File

@ -18,6 +18,8 @@ import org.hibernate.property.access.spi.SetterMethodImpl;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* {@link PropertyAccess} for accessing the wrapped property via get/set pair, which may be nonpublic. * {@link PropertyAccess} for accessing the wrapped property via get/set pair, which may be nonpublic.
* *
@ -30,7 +32,7 @@ public class PropertyAccessBasicImpl implements PropertyAccess {
private final PropertyAccessStrategyBasicImpl strategy; private final PropertyAccessStrategyBasicImpl strategy;
private final GetterMethodImpl getter; private final GetterMethodImpl getter;
private final SetterMethodImpl setter; private final @Nullable SetterMethodImpl setter;
public PropertyAccessBasicImpl( public PropertyAccessBasicImpl(
PropertyAccessStrategyBasicImpl strategy, PropertyAccessStrategyBasicImpl strategy,
@ -65,7 +67,7 @@ public class PropertyAccessBasicImpl implements PropertyAccess {
} }
@Override @Override
public Setter getSetter() { public @Nullable Setter getSetter() {
return setter; return setter;
} }
} }

View File

@ -18,6 +18,8 @@ import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.property.access.spi.PropertyAccessStrategy; import org.hibernate.property.access.spi.PropertyAccessStrategy;
import org.hibernate.property.access.spi.Setter; import org.hibernate.property.access.spi.Setter;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* {@link PropertyAccess} for accessing the wrapped property via get/set pair, which may be nonpublic. * {@link PropertyAccess} for accessing the wrapped property via get/set pair, which may be nonpublic.
* *
@ -46,18 +48,18 @@ public class PropertyAccessCompositeUserTypeImpl implements PropertyAccess, Gett
} }
@Override @Override
public Setter getSetter() { public @Nullable Setter getSetter() {
return null; return null;
} }
@Override @Override
public Object get(Object owner) { public @Nullable Object get(Object owner) {
return strategy.compositeUserType.getPropertyValue( owner, propertyIndex ); return strategy.compositeUserType.getPropertyValue( owner, propertyIndex );
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) { public @Nullable Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) {
return get( owner ); return get( owner );
} }
@ -72,17 +74,17 @@ public class PropertyAccessCompositeUserTypeImpl implements PropertyAccess, Gett
} }
@Override @Override
public Member getMember() { public @Nullable Member getMember() {
return null; return null;
} }
@Override @Override
public String getMethodName() { public @Nullable String getMethodName() {
return null; return null;
} }
@Override @Override
public Method getMethod() { public @Nullable Method getMethod() {
return null; return null;
} }
} }

View File

@ -17,6 +17,8 @@ import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.property.access.spi.PropertyAccessStrategy; import org.hibernate.property.access.spi.PropertyAccessStrategy;
import org.hibernate.property.access.spi.Setter; import org.hibernate.property.access.spi.Setter;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* {@link PropertyAccess} for handling non-aggregated composites. * {@link PropertyAccess} for handling non-aggregated composites.
* *
@ -84,17 +86,17 @@ public class PropertyAccessEmbeddedImpl implements PropertyAccess {
} }
@Override @Override
public Member getMember() { public @Nullable Member getMember() {
return null; return null;
} }
@Override @Override
public String getMethodName() { public @Nullable String getMethodName() {
return null; return null;
} }
@Override @Override
public Method getMethod() { public @Nullable Method getMethod() {
return null; return null;
} }
} }
@ -106,17 +108,17 @@ public class PropertyAccessEmbeddedImpl implements PropertyAccess {
public static final SetterImpl INSTANCE = new SetterImpl(); public static final SetterImpl INSTANCE = new SetterImpl();
@Override @Override
public void set(Object target, Object value) { public void set(Object target, @Nullable Object value) {
// nothing to do // nothing to do
} }
@Override @Override
public String getMethodName() { public @Nullable String getMethodName() {
return null; return null;
} }
@Override @Override
public Method getMethod() { public @Nullable Method getMethod() {
return null; return null;
} }
} }

View File

@ -20,6 +20,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import jakarta.persistence.AccessType; import jakarta.persistence.AccessType;
import org.checkerframework.checker.nullness.qual.Nullable;
import static org.hibernate.internal.util.ReflectHelper.findSetterMethod; import static org.hibernate.internal.util.ReflectHelper.findSetterMethod;
import static org.hibernate.internal.util.ReflectHelper.getterMethodOrNull; import static org.hibernate.internal.util.ReflectHelper.getterMethodOrNull;
@ -42,7 +43,7 @@ public class PropertyAccessEnhancedImpl implements PropertyAccess {
PropertyAccessStrategy strategy, PropertyAccessStrategy strategy,
Class<?> containerJavaType, Class<?> containerJavaType,
String propertyName, String propertyName,
AccessType getterAccessType) { @Nullable AccessType getterAccessType) {
this.strategy = strategy; this.strategy = strategy;
final AccessType propertyAccessType = resolveAccessType( getterAccessType, containerJavaType, propertyName ); final AccessType propertyAccessType = resolveAccessType( getterAccessType, containerJavaType, propertyName );
@ -80,7 +81,7 @@ public class PropertyAccessEnhancedImpl implements PropertyAccess {
} }
} }
private AccessType resolveAccessType(AccessType getterAccessType, Class<?> containerJavaType, String propertyName) { private static AccessType resolveAccessType(@Nullable AccessType getterAccessType, Class<?> containerJavaType, String propertyName) {
if ( getterAccessType != null ) { if ( getterAccessType != null ) {
// this should indicate FIELD access // this should indicate FIELD access
return getterAccessType; return getterAccessType;

View File

@ -17,6 +17,8 @@ import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.property.access.spi.PropertyAccessStrategy; import org.hibernate.property.access.spi.PropertyAccessStrategy;
import org.hibernate.property.access.spi.Setter; import org.hibernate.property.access.spi.Setter;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* {@link PropertyAccess} implementation that deals with an underlying {@code Map} * {@link PropertyAccess} implementation that deals with an underlying {@code Map}
* as the container, using {@link Map#get} and {@link Map#put}. * as the container, using {@link Map#get} and {@link Map#put}.
@ -59,12 +61,12 @@ public class PropertyAccessMapImpl implements PropertyAccess {
@Override @Override
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public Object get(Object owner) { public @Nullable Object get(Object owner) {
return ( (Map) owner ).get( propertyName ); return ( (Map) owner ).get( propertyName );
} }
@Override @Override
public Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) { public @Nullable Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) {
return get( owner ); return get( owner );
} }
@ -80,17 +82,17 @@ public class PropertyAccessMapImpl implements PropertyAccess {
} }
@Override @Override
public Member getMember() { public @Nullable Member getMember() {
return null; return null;
} }
@Override @Override
public String getMethodName() { public @Nullable String getMethodName() {
return null; return null;
} }
@Override @Override
public Method getMethod() { public @Nullable Method getMethod() {
return null; return null;
} }
} }
@ -104,17 +106,17 @@ public class PropertyAccessMapImpl implements PropertyAccess {
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void set(Object target, Object value) { public void set(Object target, @Nullable Object value) {
( (Map) target ).put( propertyName, value ); ( (Map) target ).put( propertyName, value );
} }
@Override @Override
public String getMethodName() { public @Nullable String getMethodName() {
return null; return null;
} }
@Override @Override
public Method getMethod() { public @Nullable Method getMethod() {
return null; return null;
} }
} }

View File

@ -20,6 +20,7 @@ import org.hibernate.property.access.spi.SetterFieldImpl;
import org.hibernate.property.access.spi.SetterMethodImpl; import org.hibernate.property.access.spi.SetterMethodImpl;
import jakarta.persistence.AccessType; import jakarta.persistence.AccessType;
import org.checkerframework.checker.nullness.qual.PolyNull;
import static org.hibernate.internal.util.ReflectHelper.findSetterMethod; import static org.hibernate.internal.util.ReflectHelper.findSetterMethod;
import static org.hibernate.internal.util.ReflectHelper.getterMethodOrNull; import static org.hibernate.internal.util.ReflectHelper.getterMethodOrNull;
@ -74,19 +75,19 @@ public class PropertyAccessMixedImpl implements PropertyAccess {
// --- // // --- //
protected Getter fieldGetter(Class<?> containerJavaType, String propertyName, Field field) { private static Getter fieldGetter(Class<?> containerJavaType, String propertyName, Field field) {
return new GetterFieldImpl( containerJavaType, propertyName, field ); return new GetterFieldImpl( containerJavaType, propertyName, field );
} }
protected Setter fieldSetter(Class<?> containerJavaType, String propertyName, Field field) { private static Setter fieldSetter(Class<?> containerJavaType, String propertyName, Field field) {
return new SetterFieldImpl( containerJavaType, propertyName, field ); return new SetterFieldImpl( containerJavaType, propertyName, field );
} }
protected Getter propertyGetter(Class<?> containerJavaType, String propertyName, Method method) { private static Getter propertyGetter(Class<?> containerJavaType, String propertyName, Method method) {
return new GetterMethodImpl( containerJavaType, propertyName, method ); return new GetterMethodImpl( containerJavaType, propertyName, method );
} }
protected Setter propertySetter(Class<?> containerJavaType, String propertyName, Method method) { private static @PolyNull Setter propertySetter(Class<?> containerJavaType, String propertyName, @PolyNull Method method) {
return method == null ? null : new SetterMethodImpl( containerJavaType, propertyName, method ); return method == null ? null : new SetterMethodImpl( containerJavaType, propertyName, method );
} }

View File

@ -18,6 +18,8 @@ import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.property.access.spi.PropertyAccessStrategy; import org.hibernate.property.access.spi.PropertyAccessStrategy;
import org.hibernate.property.access.spi.Setter; import org.hibernate.property.access.spi.Setter;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* @author Gavin King * @author Gavin King
* @author Steve Ebersole * @author Steve Ebersole
@ -94,13 +96,8 @@ public class PropertyAccessStrategyBackRefImpl implements PropertyAccessStrategy
@Override @Override
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) { public Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) {
if ( session == null ) {
return UNKNOWN;
}
else {
return session.getPersistenceContextInternal().getOwnerId( entityName, propertyName, owner, mergeMap ); return session.getPersistenceContextInternal().getOwnerId( entityName, propertyName, owner, mergeMap );
} }
}
@Override @Override
public Class<?> getReturnTypeClass() { public Class<?> getReturnTypeClass() {
@ -113,17 +110,17 @@ public class PropertyAccessStrategyBackRefImpl implements PropertyAccessStrategy
} }
@Override @Override
public Member getMember() { public @Nullable Member getMember() {
return null; return null;
} }
@Override @Override
public String getMethodName() { public @Nullable String getMethodName() {
return null; return null;
} }
@Override @Override
public Method getMethod() { public @Nullable Method getMethod() {
return null; return null;
} }
} }
@ -135,17 +132,17 @@ public class PropertyAccessStrategyBackRefImpl implements PropertyAccessStrategy
public static final SetterImpl INSTANCE = new SetterImpl(); public static final SetterImpl INSTANCE = new SetterImpl();
@Override @Override
public void set(Object target, Object value) { public void set(Object target, @Nullable Object value) {
// this page intentionally left blank :) // this page intentionally left blank :)
} }
@Override @Override
public String getMethodName() { public @Nullable String getMethodName() {
return null; return null;
} }
@Override @Override
public Method getMethod() { public @Nullable Method getMethod() {
return null; return null;
} }
} }

View File

@ -10,6 +10,7 @@ import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.property.access.spi.PropertyAccessStrategy; import org.hibernate.property.access.spi.PropertyAccessStrategy;
import jakarta.persistence.AccessType; import jakarta.persistence.AccessType;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* Defines a strategy for accessing property values via a get/set pair, which may be nonpublic. This * Defines a strategy for accessing property values via a get/set pair, which may be nonpublic. This
@ -26,12 +27,12 @@ public class PropertyAccessStrategyEnhancedImpl implements PropertyAccessStrateg
return STANDARD; return STANDARD;
} }
private final AccessType getterAccessType; private final @Nullable AccessType getterAccessType;
public static PropertyAccessStrategyEnhancedImpl STANDARD = new PropertyAccessStrategyEnhancedImpl( null ); public static PropertyAccessStrategyEnhancedImpl STANDARD = new PropertyAccessStrategyEnhancedImpl( null );
public static PropertyAccessStrategyEnhancedImpl FIELD = new PropertyAccessStrategyEnhancedImpl( AccessType.FIELD ); public static PropertyAccessStrategyEnhancedImpl FIELD = new PropertyAccessStrategyEnhancedImpl( AccessType.FIELD );
public PropertyAccessStrategyEnhancedImpl(AccessType getterAccessType) { public PropertyAccessStrategyEnhancedImpl(@Nullable AccessType getterAccessType) {
this.getterAccessType = getterAccessType; this.getterAccessType = getterAccessType;
} }

View File

@ -17,6 +17,8 @@ import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.property.access.spi.PropertyAccessStrategy; import org.hibernate.property.access.spi.PropertyAccessStrategy;
import org.hibernate.property.access.spi.Setter; import org.hibernate.property.access.spi.Setter;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* @author Gavin King * @author Gavin King
* @author Steve Ebersole * @author Steve Ebersole
@ -77,13 +79,8 @@ public class PropertyAccessStrategyIndexBackRefImpl implements PropertyAccessStr
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) { public Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) {
if ( session == null ) {
return PropertyAccessStrategyBackRefImpl.UNKNOWN;
}
else {
return session.getPersistenceContextInternal().getIndexInOwner( entityName, propertyName, owner, mergeMap ); return session.getPersistenceContextInternal().getIndexInOwner( entityName, propertyName, owner, mergeMap );
} }
}
@Override @Override
public Class<?> getReturnTypeClass() { public Class<?> getReturnTypeClass() {
@ -96,17 +93,17 @@ public class PropertyAccessStrategyIndexBackRefImpl implements PropertyAccessStr
} }
@Override @Override
public Member getMember() { public @Nullable Member getMember() {
return null; return null;
} }
@Override @Override
public String getMethodName() { public @Nullable String getMethodName() {
return null; return null;
} }
@Override @Override
public Method getMethod() { public @Nullable Method getMethod() {
return null; return null;
} }
} }
@ -118,17 +115,17 @@ public class PropertyAccessStrategyIndexBackRefImpl implements PropertyAccessStr
public static final SetterImpl INSTANCE = new SetterImpl(); public static final SetterImpl INSTANCE = new SetterImpl();
@Override @Override
public void set(Object target, Object value) { public void set(Object target, @Nullable Object value) {
// this page intentionally left blank :) // this page intentionally left blank :)
} }
@Override @Override
public String getMethodName() { public @Nullable String getMethodName() {
return null; return null;
} }
@Override @Override
public Method getMethod() { public @Nullable Method getMethod() {
return null; return null;
} }
} }

View File

@ -11,6 +11,8 @@ import java.util.Map;
import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.property.access.spi.PropertyAccessStrategy; import org.hibernate.property.access.spi.PropertyAccessStrategy;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
* @author Gavin King * @author Gavin King
@ -22,7 +24,7 @@ public class PropertyAccessStrategyMapImpl implements PropertyAccessStrategy {
public static final PropertyAccessStrategyMapImpl INSTANCE = new PropertyAccessStrategyMapImpl(); public static final PropertyAccessStrategyMapImpl INSTANCE = new PropertyAccessStrategyMapImpl();
@Override @Override
public PropertyAccess buildPropertyAccess(Class<?> containerJavaType, String propertyName, boolean setterRequired) { public PropertyAccess buildPropertyAccess(@Nullable Class<?> containerJavaType, String propertyName, boolean setterRequired) {
// Sometimes containerJavaType is null, but if it isn't, make sure it's a Map. // Sometimes containerJavaType is null, but if it isn't, make sure it's a Map.
if (containerJavaType != null && !Map.class.isAssignableFrom( containerJavaType)) { if (containerJavaType != null && !Map.class.isAssignableFrom( containerJavaType)) {

View File

@ -17,6 +17,8 @@ import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.property.access.spi.PropertyAccessStrategy; import org.hibernate.property.access.spi.PropertyAccessStrategy;
import org.hibernate.property.access.spi.Setter; import org.hibernate.property.access.spi.Setter;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* @author Michael Bartmann * @author Michael Bartmann
* @author Gavin King * @author Gavin King
@ -62,13 +64,13 @@ public class PropertyAccessStrategyNoopImpl implements PropertyAccessStrategy {
public static final GetterImpl INSTANCE = new GetterImpl(); public static final GetterImpl INSTANCE = new GetterImpl();
@Override @Override
public Object get(Object owner) { public @Nullable Object get(Object owner) {
return null; return null;
} }
@Override @Override
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) { public @Nullable Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) {
return null; return null;
} }
@ -83,17 +85,17 @@ public class PropertyAccessStrategyNoopImpl implements PropertyAccessStrategy {
} }
@Override @Override
public Member getMember() { public @Nullable Member getMember() {
return null; return null;
} }
@Override @Override
public String getMethodName() { public @Nullable String getMethodName() {
return null; return null;
} }
@Override @Override
public Method getMethod() { public @Nullable Method getMethod() {
return null; return null;
} }
} }
@ -105,16 +107,16 @@ public class PropertyAccessStrategyNoopImpl implements PropertyAccessStrategy {
public static final SetterImpl INSTANCE = new SetterImpl(); public static final SetterImpl INSTANCE = new SetterImpl();
@Override @Override
public void set(Object target, Object value) { public void set(Object target, @Nullable Object value) {
} }
@Override @Override
public String getMethodName() { public @Nullable String getMethodName() {
return null; return null;
} }
@Override @Override
public Method getMethod() { public @Nullable Method getMethod() {
return null; return null;
} }
} }

View File

@ -8,6 +8,7 @@ package org.hibernate.property.access.internal;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.boot.registry.selector.spi.StrategySelector; import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.internal.util.NullnessUtil;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.RepresentationMode; import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.property.access.spi.BuiltInPropertyAccessStrategies; import org.hibernate.property.access.spi.BuiltInPropertyAccessStrategies;
@ -79,7 +80,7 @@ public class PropertyAccessStrategyResolverStandardImpl implements PropertyAcces
if ( serviceRegistry == null ) { if ( serviceRegistry == null ) {
throw new HibernateException( "ServiceRegistry not yet injected; PropertyAccessStrategyResolver not ready for use." ); throw new HibernateException( "ServiceRegistry not yet injected; PropertyAccessStrategyResolver not ready for use." );
} }
strategySelectorService = serviceRegistry.getService( StrategySelector.class ); strategySelectorService = NullnessUtil.castNonNull( serviceRegistry.getService( StrategySelector.class ) );
} }
return strategySelectorService; return strategySelectorService;
} }

View File

@ -13,6 +13,8 @@ import org.hibernate.property.access.internal.PropertyAccessStrategyMapImpl;
import org.hibernate.property.access.internal.PropertyAccessStrategyMixedImpl; import org.hibernate.property.access.internal.PropertyAccessStrategyMixedImpl;
import org.hibernate.property.access.internal.PropertyAccessStrategyNoopImpl; import org.hibernate.property.access.internal.PropertyAccessStrategyNoopImpl;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* Describes the built-in externally-nameable {@link PropertyAccessStrategy} implementations. * Describes the built-in externally-nameable {@link PropertyAccessStrategy} implementations.
* *
@ -42,7 +44,7 @@ public enum BuiltInPropertyAccessStrategies {
return strategy; return strategy;
} }
public static BuiltInPropertyAccessStrategies interpret(String name) { public static @Nullable BuiltInPropertyAccessStrategies interpret(String name) {
for ( BuiltInPropertyAccessStrategies strategy : values() ) { for ( BuiltInPropertyAccessStrategies strategy : values() ) {
if ( strategy.externalName.equals( name ) ) { if ( strategy.externalName.equals( name ) ) {
return strategy; return strategy;

View File

@ -13,6 +13,8 @@ import org.hibernate.Internal;
import org.hibernate.property.access.internal.AbstractFieldSerialForm; import org.hibernate.property.access.internal.AbstractFieldSerialForm;
import org.hibernate.property.access.internal.AccessStrategyHelper; import org.hibernate.property.access.internal.AccessStrategyHelper;
import org.checkerframework.checker.nullness.qual.Nullable;
import static org.hibernate.property.access.internal.AccessStrategyHelper.determineEnhancementState; import static org.hibernate.property.access.internal.AccessStrategyHelper.determineEnhancementState;
/** /**
@ -36,7 +38,7 @@ public class EnhancedSetterImpl extends SetterFieldImpl {
} }
@Override @Override
public void set(Object target, Object value) { public void set(Object target, @Nullable Object value) {
super.set( target, value ); super.set( target, value );
AccessStrategyHelper.handleEnhancedInjection( target, value, enhancementState, propertyName ); AccessStrategyHelper.handleEnhancedInjection( target, value, enhancementState, propertyName );
} }

View File

@ -13,6 +13,8 @@ import org.hibernate.Internal;
import org.hibernate.property.access.internal.AbstractSetterMethodSerialForm; import org.hibernate.property.access.internal.AbstractSetterMethodSerialForm;
import org.hibernate.property.access.internal.AccessStrategyHelper; import org.hibernate.property.access.internal.AccessStrategyHelper;
import org.checkerframework.checker.nullness.qual.Nullable;
import static org.hibernate.property.access.internal.AccessStrategyHelper.determineEnhancementState; import static org.hibernate.property.access.internal.AccessStrategyHelper.determineEnhancementState;
/** /**
@ -35,7 +37,7 @@ public class EnhancedSetterMethodImpl extends SetterMethodImpl {
} }
@Override @Override
public void set(Object target, Object value) { public void set(Object target, @Nullable Object value) {
super.set( target, value ); super.set( target, value );
AccessStrategyHelper.handleEnhancedInjection( target, value, enhancementState, propertyName ); AccessStrategyHelper.handleEnhancedInjection( target, value, enhancementState, propertyName );

View File

@ -14,6 +14,8 @@ import java.util.Map;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* The contract for getting the value of a persistent attribute from its container/owner. * The contract for getting the value of a persistent attribute from its container/owner.
* *
@ -28,7 +30,7 @@ public interface Getter extends Serializable {
* *
* @return The extracted value. * @return The extracted value.
*/ */
Object get(Object owner); @Nullable Object get(Object owner);
/** /**
* Get the property value from the given owner instance. * Get the property value from the given owner instance.
@ -39,7 +41,7 @@ public interface Getter extends Serializable {
* *
* @return The extracted value. * @return The extracted value.
*/ */
Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session); @Nullable Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session);
/** /**
* Retrieve the declared Java type class * Retrieve the declared Java type class
@ -63,7 +65,7 @@ public interface Getter extends Serializable {
* *
* @return The mapped member, or {@code null}. * @return The mapped member, or {@code null}.
*/ */
Member getMember(); @Nullable Member getMember();
/** /**
* Retrieve the getter-method name. * Retrieve the getter-method name.
@ -72,7 +74,7 @@ public interface Getter extends Serializable {
* *
* @return The name of the getter method, or {@code null}. * @return The name of the getter method, or {@code null}.
*/ */
String getMethodName(); @Nullable String getMethodName();
/** /**
* Retrieve the getter-method. * Retrieve the getter-method.
@ -81,5 +83,5 @@ public interface Getter extends Serializable {
* *
* @return The getter method, or {@code null}. * @return The getter method, or {@code null}.
*/ */
Method getMethod(); @Nullable Method getMethod();
} }

View File

@ -20,6 +20,8 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.property.access.internal.AbstractFieldSerialForm; import org.hibernate.property.access.internal.AbstractFieldSerialForm;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* Field-based implementation of Getter * Field-based implementation of Getter
* *
@ -30,7 +32,7 @@ public class GetterFieldImpl implements Getter {
private final Class<?> containerClass; private final Class<?> containerClass;
private final String propertyName; private final String propertyName;
private final Field field; private final Field field;
private final Method getterMethod; private final @Nullable Method getterMethod;
public GetterFieldImpl(Class<?> containerClass, String propertyName, Field field) { public GetterFieldImpl(Class<?> containerClass, String propertyName, Field field) {
this.containerClass = containerClass; this.containerClass = containerClass;
@ -41,7 +43,7 @@ public class GetterFieldImpl implements Getter {
} }
@Override @Override
public Object get(Object owner) { public @Nullable Object get(Object owner) {
try { try {
return field.get( owner ); return field.get( owner );
} }
@ -62,7 +64,7 @@ public class GetterFieldImpl implements Getter {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) { public @Nullable Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) {
return get( owner ); return get( owner );
} }
@ -82,12 +84,12 @@ public class GetterFieldImpl implements Getter {
} }
@Override @Override
public String getMethodName() { public @Nullable String getMethodName() {
return getterMethod != null ? getterMethod.getName() : null; return getterMethod != null ? getterMethod.getName() : null;
} }
@Override @Override
public Method getMethod() { public @Nullable Method getMethod() {
return getterMethod; return getterMethod;
} }

View File

@ -21,6 +21,8 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.ArrayHelper;
import org.checkerframework.checker.nullness.qual.Nullable;
import static org.hibernate.internal.CoreLogging.messageLogger; import static org.hibernate.internal.CoreLogging.messageLogger;
/** /**
@ -41,7 +43,7 @@ public class GetterMethodImpl implements Getter {
} }
@Override @Override
public Object get(Object owner) { public @Nullable Object get(Object owner) {
try { try {
return getterMethod.invoke( owner, ArrayHelper.EMPTY_OBJECT_ARRAY ); return getterMethod.invoke( owner, ArrayHelper.EMPTY_OBJECT_ARRAY );
} }
@ -83,7 +85,7 @@ public class GetterMethodImpl implements Getter {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) { public @Nullable Object getForInsert(Object owner, Map mergeMap, SharedSessionContractImplementor session) {
return get( owner ); return get( owner );
} }

View File

@ -8,6 +8,8 @@ package org.hibernate.property.access.spi;
import org.hibernate.metamodel.spi.ManagedTypeRepresentationStrategy; import org.hibernate.metamodel.spi.ManagedTypeRepresentationStrategy;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* Defines how a given persistent attribute is accessed by exposing * Defines how a given persistent attribute is accessed by exposing
* a {@link Getter} and a {@link Setter} for the attribute. * a {@link Getter} and a {@link Setter} for the attribute.
@ -39,5 +41,5 @@ public interface PropertyAccess {
* *
* @return The property setter * @return The property setter
*/ */
Setter getSetter(); @Nullable Setter getSetter();
} }

View File

@ -9,6 +9,8 @@ package org.hibernate.property.access.spi;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* The contract for setting the value of a persistent attribute on its container/owner. * The contract for setting the value of a persistent attribute on its container/owner.
* *
@ -17,15 +19,15 @@ import java.lang.reflect.Method;
*/ */
public interface Setter extends Serializable { public interface Setter extends Serializable {
void set(Object target, Object value); void set(Object target, @Nullable Object value);
/** /**
* Optional operation (may return {@code null}) * Optional operation (may return {@code null})
*/ */
String getMethodName(); @Nullable String getMethodName();
/** /**
* Optional operation (may return {@code null}) * Optional operation (may return {@code null})
*/ */
Method getMethod(); @Nullable Method getMethod();
} }

View File

@ -18,6 +18,8 @@ import org.hibernate.property.access.internal.AbstractFieldSerialForm;
import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer; import org.hibernate.proxy.LazyInitializer;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* Field-based implementation of Setter * Field-based implementation of Setter
* *
@ -28,7 +30,7 @@ public class SetterFieldImpl implements Setter {
private final Class<?> containerClass; private final Class<?> containerClass;
private final String propertyName; private final String propertyName;
private final Field field; private final Field field;
private final Method setterMethod; private final @Nullable Method setterMethod;
public SetterFieldImpl(Class<?> containerClass, String propertyName, Field field) { public SetterFieldImpl(Class<?> containerClass, String propertyName, Field field) {
this.containerClass = containerClass; this.containerClass = containerClass;
@ -50,7 +52,7 @@ public class SetterFieldImpl implements Setter {
} }
@Override @Override
public void set(Object target, Object value) { public void set(Object target, @Nullable Object value) {
try { try {
field.set( target, value ); field.set( target, value );
} }
@ -97,12 +99,12 @@ public class SetterFieldImpl implements Setter {
} }
@Override @Override
public String getMethodName() { public @Nullable String getMethodName() {
return setterMethod != null ? setterMethod.getName() : null; return setterMethod != null ? setterMethod.getName() : null;
} }
@Override @Override
public Method getMethod() { public @Nullable Method getMethod() {
return setterMethod; return setterMethod;
} }

View File

@ -16,6 +16,8 @@ import org.hibernate.PropertySetterAccessException;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.property.access.internal.AbstractSetterMethodSerialForm; import org.hibernate.property.access.internal.AbstractSetterMethodSerialForm;
import org.checkerframework.checker.nullness.qual.Nullable;
import static org.hibernate.internal.CoreLogging.messageLogger; import static org.hibernate.internal.CoreLogging.messageLogger;
/** /**
@ -40,7 +42,7 @@ public class SetterMethodImpl implements Setter {
} }
@Override @Override
public void set(Object target, Object value) { public void set(Object target, @Nullable Object value) {
try { try {
setterMethod.invoke( target, value ); setterMethod.invoke( target, value );
} }

View File

@ -10,6 +10,8 @@ import java.io.Serializable;
import org.hibernate.Internal; import org.hibernate.Internal;
import org.hibernate.engine.spi.PrimeAmongSecondarySupertypes; import org.hibernate.engine.spi.PrimeAmongSecondarySupertypes;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* Interface implemented directly by entity proxies, exposing * Interface implemented directly by entity proxies, exposing
* access to the associated {@link LazyInitializer}. * access to the associated {@link LazyInitializer}.
@ -27,7 +29,7 @@ public interface HibernateProxy extends Serializable, PrimeAmongSecondarySuperty
* @return the associated {@link LazyInitializer} if the given * @return the associated {@link LazyInitializer} if the given
* object is a proxy, or {@code null} otherwise. * object is a proxy, or {@code null} otherwise.
*/ */
static LazyInitializer extractLazyInitializer(final Object object) { static @Nullable LazyInitializer extractLazyInitializer(final @Nullable Object object) {
if ( object instanceof PrimeAmongSecondarySupertypes ) { if ( object instanceof PrimeAmongSecondarySupertypes ) {
PrimeAmongSecondarySupertypes t = (PrimeAmongSecondarySupertypes) object; PrimeAmongSecondarySupertypes t = (PrimeAmongSecondarySupertypes) object;
final HibernateProxy hibernateProxy = t.asHibernateProxy(); final HibernateProxy hibernateProxy = t.asHibernateProxy();