diff --git a/src/main/java/org/springframework/data/domain/AbstractAggregateRoot.java b/src/main/java/org/springframework/data/domain/AbstractAggregateRoot.java index a6a89fbf6..9f4606715 100644 --- a/src/main/java/org/springframework/data/domain/AbstractAggregateRoot.java +++ b/src/main/java/org/springframework/data/domain/AbstractAggregateRoot.java @@ -75,6 +75,7 @@ public class AbstractAggregateRoot> { * @param aggregate must not be {@literal null}. * @return the aggregate */ + @SuppressWarnings("unchecked") protected final A andEventsFrom(A aggregate) { Assert.notNull(aggregate, "Aggregate must not be null!"); @@ -92,6 +93,7 @@ public class AbstractAggregateRoot> { * @return the aggregate * @see #registerEvent(Object) */ + @SuppressWarnings("unchecked") protected final A andEvent(Object event) { registerEvent(event); diff --git a/src/main/java/org/springframework/data/mapping/model/AbstractPersistentProperty.java b/src/main/java/org/springframework/data/mapping/model/AbstractPersistentProperty.java index 35a096dac..d20605d5b 100644 --- a/src/main/java/org/springframework/data/mapping/model/AbstractPersistentProperty.java +++ b/src/main/java/org/springframework/data/mapping/model/AbstractPersistentProperty.java @@ -56,6 +56,7 @@ public abstract class AbstractPersistentProperty

private final Lazy> association; private final @Getter PersistentEntity owner; + @SuppressWarnings("null") // private final @Getter(value = AccessLevel.PROTECTED, onMethod = @__(@SuppressWarnings("null"))) Property property; private final Lazy hashCode; private final Lazy usePropertyAccess; diff --git a/src/main/java/org/springframework/data/projection/DefaultMethodInvokingMethodInterceptor.java b/src/main/java/org/springframework/data/projection/DefaultMethodInvokingMethodInterceptor.java index bebb10fbe..297419cb4 100644 --- a/src/main/java/org/springframework/data/projection/DefaultMethodInvokingMethodInterceptor.java +++ b/src/main/java/org/springframework/data/projection/DefaultMethodInvokingMethodInterceptor.java @@ -133,8 +133,8 @@ public class DefaultMethodInvokingMethodInterceptor implements MethodInterceptor MethodType methodType = MethodType.methodType(method.getReturnType(), method.getParameterTypes()); - return getLookup(method.getDeclaringClass()).findSpecial(method.getDeclaringClass(), method.getName(), - methodType, method.getDeclaringClass()); + return getLookup(method.getDeclaringClass(), privateLookupIn).findSpecial(method.getDeclaringClass(), + method.getName(), methodType, method.getDeclaringClass()); } /* @@ -146,14 +146,14 @@ public class DefaultMethodInvokingMethodInterceptor implements MethodInterceptor return true; } - private Lookup getLookup(Class declaringClass) { - - Lookup lookup = MethodHandles.lookup(); + private Lookup getLookup(Class declaringClass, @Nullable Method privateLookupIn) { if (privateLookupIn == null) { - return lookup; + return MethodHandles.lookup(); } + Lookup lookup = MethodHandles.lookup(); + try { return (Lookup) privateLookupIn.invoke(MethodHandles.class, declaringClass, lookup); } catch (ReflectiveOperationException e) { diff --git a/src/main/java/org/springframework/data/repository/core/support/MethodInvocationValidator.java b/src/main/java/org/springframework/data/repository/core/support/MethodInvocationValidator.java index 29bea7947..37ad2373b 100644 --- a/src/main/java/org/springframework/data/repository/core/support/MethodInvocationValidator.java +++ b/src/main/java/org/springframework/data/repository/core/support/MethodInvocationValidator.java @@ -70,7 +70,7 @@ public class MethodInvocationValidator implements MethodInterceptor { */ @Nullable @Override - public Object invoke(MethodInvocation invocation) throws Throwable { + public Object invoke(@SuppressWarnings("null") MethodInvocation invocation) throws Throwable { Method method = invocation.getMethod(); Nullability nullability = nullabilityCache.get(method); diff --git a/src/main/java/org/springframework/data/repository/init/AbstractRepositoryPopulatorFactoryBean.java b/src/main/java/org/springframework/data/repository/init/AbstractRepositoryPopulatorFactoryBean.java index 3e1c85832..27d2c3997 100644 --- a/src/main/java/org/springframework/data/repository/init/AbstractRepositoryPopulatorFactoryBean.java +++ b/src/main/java/org/springframework/data/repository/init/AbstractRepositoryPopulatorFactoryBean.java @@ -15,6 +15,8 @@ */ package org.springframework.data.repository.init; +import javax.annotation.Nonnull; + import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.context.ApplicationContext; @@ -37,7 +39,7 @@ public abstract class AbstractRepositoryPopulatorFactoryBean extends AbstractFactoryBean implements ApplicationListener, ApplicationContextAware { - private @Nullable Resource[] resources; + private Resource[] resources = new Resource[0]; private @Nullable RepositoryPopulator populator; private @Nullable ApplicationContext context; @@ -64,6 +66,7 @@ public abstract class AbstractRepositoryPopulatorFactoryBean * (non-Javadoc) * @see org.springframework.beans.factory.config.AbstractFactoryBean#getObjectType() */ + @Nonnull @Override public Class getObjectType() { return ResourceReaderRepositoryPopulator.class; @@ -78,7 +81,10 @@ public abstract class AbstractRepositoryPopulatorFactoryBean ResourceReaderRepositoryPopulator initializer = new ResourceReaderRepositoryPopulator(getResourceReader()); initializer.setResources(resources); - initializer.setApplicationEventPublisher(context); + + if (context != null) { + initializer.setApplicationEventPublisher(context); + } this.populator = initializer; @@ -91,7 +97,14 @@ public abstract class AbstractRepositoryPopulatorFactoryBean */ public void onApplicationEvent(ContextRefreshedEvent event) { + RepositoryPopulator populator = this.populator; + + if (populator == null) { + throw new IllegalStateException("RepositoryPopulator was not properly initialized!"); + } + if (event.getApplicationContext().equals(context)) { + Repositories repositories = new Repositories(event.getApplicationContext()); populator.populate(repositories); } @@ -99,6 +112,10 @@ public abstract class AbstractRepositoryPopulatorFactoryBean protected abstract ResourceReader getResourceReader(); + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.config.AbstractFactoryBean#afterPropertiesSet() + */ @Override public void afterPropertiesSet() throws Exception { diff --git a/src/main/java/org/springframework/data/repository/init/UnmarshallerRepositoryPopulatorFactoryBean.java b/src/main/java/org/springframework/data/repository/init/UnmarshallerRepositoryPopulatorFactoryBean.java index afb50223d..a72efb254 100644 --- a/src/main/java/org/springframework/data/repository/init/UnmarshallerRepositoryPopulatorFactoryBean.java +++ b/src/main/java/org/springframework/data/repository/init/UnmarshallerRepositoryPopulatorFactoryBean.java @@ -44,6 +44,13 @@ public class UnmarshallerRepositoryPopulatorFactoryBean extends AbstractReposito */ @Override protected ResourceReader getResourceReader() { + + Unmarshaller unmarshaller = this.unmarshaller; + + if (unmarshaller == null) { + throw new IllegalStateException("No Unmarshaller configured!"); + } + return new UnmarshallingResourceReader(unmarshaller); } diff --git a/src/main/java/org/springframework/data/repository/query/ReturnedType.java b/src/main/java/org/springframework/data/repository/query/ReturnedType.java index 7921ec18b..2e11fc34c 100644 --- a/src/main/java/org/springframework/data/repository/query/ReturnedType.java +++ b/src/main/java/org/springframework/data/repository/query/ReturnedType.java @@ -290,7 +290,6 @@ public abstract class ReturnedType { return inputProperties; } - @SuppressWarnings({ "unchecked", "rawtypes" }) private List detectConstructorParameterNames(Class type) { if (!isDto()) { diff --git a/src/main/java/org/springframework/data/repository/query/parser/AbstractQueryCreator.java b/src/main/java/org/springframework/data/repository/query/parser/AbstractQueryCreator.java index a10a3a029..c3687cf55 100644 --- a/src/main/java/org/springframework/data/repository/query/parser/AbstractQueryCreator.java +++ b/src/main/java/org/springframework/data/repository/query/parser/AbstractQueryCreator.java @@ -23,6 +23,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree.OrPart; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -101,6 +102,7 @@ public abstract class AbstractQueryCreator { * @param tree must not be {@literal null}. * @return */ + @Nullable private S createCriteria(PartTree tree) { S base = null; @@ -108,11 +110,16 @@ public abstract class AbstractQueryCreator { for (OrPart node : tree) { - S criteria = null; + Iterator parts = node.iterator(); - for (Part part : node) { + if (!parts.hasNext()) { + throw new IllegalStateException(String.format("No part found in PartTree %s!", tree)); + } + + S criteria = create(parts.next(), iterator); - criteria = criteria == null ? create(part, iterator) : and(part, criteria, iterator); + while (parts.hasNext()) { + criteria = and(parts.next(), criteria, iterator); } base = base == null ? criteria : or(base, criteria); @@ -152,9 +159,9 @@ public abstract class AbstractQueryCreator { /** * Actually creates the query object applying the given criteria object and {@link Sort} definition. * - * @param criteria will never be {@literal null}. + * @param criteria can be {@literal null}. * @param sort must not be {@literal null}. * @return */ - protected abstract T complete(S criteria, Sort sort); + protected abstract T complete(@Nullable S criteria, Sort sort); } diff --git a/src/main/java/org/springframework/data/repository/query/parser/Part.java b/src/main/java/org/springframework/data/repository/query/parser/Part.java index f5c9d9387..b6da98f80 100644 --- a/src/main/java/org/springframework/data/repository/query/parser/Part.java +++ b/src/main/java/org/springframework/data/repository/query/parser/Part.java @@ -235,10 +235,6 @@ public class Part { */ protected boolean supports(String property) { - if (keywords == null) { - return true; - } - for (String keyword : keywords) { if (property.endsWith(keyword)) { return true; diff --git a/src/main/java/org/springframework/data/repository/query/spi/EvaluationContextExtension.java b/src/main/java/org/springframework/data/repository/query/spi/EvaluationContextExtension.java index 0679c2919..9513ef58b 100644 --- a/src/main/java/org/springframework/data/repository/query/spi/EvaluationContextExtension.java +++ b/src/main/java/org/springframework/data/repository/query/spi/EvaluationContextExtension.java @@ -19,6 +19,7 @@ import java.util.Map; import org.springframework.data.repository.query.ExtensionAwareEvaluationContextProvider; import org.springframework.expression.EvaluationContext; +import org.springframework.lang.Nullable; /** * SPI to allow adding a set of properties and function definitions accessible via the root of an @@ -59,5 +60,6 @@ public interface EvaluationContextExtension { * * @return */ + @Nullable Object getRootObject(); } diff --git a/src/main/java/org/springframework/data/repository/query/spi/EvaluationContextExtensionSupport.java b/src/main/java/org/springframework/data/repository/query/spi/EvaluationContextExtensionSupport.java index 875c74be6..21e041fe2 100644 --- a/src/main/java/org/springframework/data/repository/query/spi/EvaluationContextExtensionSupport.java +++ b/src/main/java/org/springframework/data/repository/query/spi/EvaluationContextExtensionSupport.java @@ -18,6 +18,8 @@ package org.springframework.data.repository.query.spi; import java.util.Collections; import java.util.Map; +import org.springframework.lang.Nullable; + /** * A base class for {@link EvaluationContextExtension}s. * @@ -49,6 +51,7 @@ public abstract class EvaluationContextExtensionSupport implements EvaluationCon * (non-Javadoc) * @see org.springframework.data.repository.query.spi.EvaluationContextExtension#getRootObject() */ + @Nullable @Override public Object getRootObject() { return null; diff --git a/src/main/java/org/springframework/data/repository/query/spi/Function.java b/src/main/java/org/springframework/data/repository/query/spi/Function.java index 97b3006a5..592b19f9a 100644 --- a/src/main/java/org/springframework/data/repository/query/spi/Function.java +++ b/src/main/java/org/springframework/data/repository/query/spi/Function.java @@ -21,6 +21,7 @@ import java.util.Arrays; import java.util.List; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.TypeUtils; @@ -36,7 +37,7 @@ import org.springframework.util.TypeUtils; public class Function { private final Method method; - private final Object target; + private final @Nullable Object target; /** * Creates a new {@link Function} to statically invoke the given {@link Method}. @@ -56,7 +57,7 @@ public class Function { * @param method must not be {@literal null}. * @param target can be {@literal null}, if so, the method */ - public Function(Method method, Object target) { + public Function(Method method, @Nullable Object target) { Assert.notNull(method, "Method must not be null!"); Assert.isTrue(target != null || Modifier.isStatic(method.getModifiers()), @@ -154,7 +155,6 @@ public class Function { * Checks wether this {@code Function} has the same signature as another {@code Function}. * * @param other the {@code Function} to compare {@code this} with. - * * @return {@code true} iff name and argument list are the same. */ public boolean isSignatureEqual(Function other) { diff --git a/src/main/java/org/springframework/data/transaction/ChainedTransactionManager.java b/src/main/java/org/springframework/data/transaction/ChainedTransactionManager.java index d47c21337..1a2eebf7e 100644 --- a/src/main/java/org/springframework/data/transaction/ChainedTransactionManager.java +++ b/src/main/java/org/springframework/data/transaction/ChainedTransactionManager.java @@ -25,6 +25,7 @@ import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.lang.Nullable; import org.springframework.transaction.CannotCreateTransactionException; import org.springframework.transaction.HeuristicCompletionException; import org.springframework.transaction.PlatformTransactionManager; @@ -86,10 +87,14 @@ public class ChainedTransactionManager implements PlatformTransactionManager { * (non-Javadoc) * @see org.springframework.transaction.PlatformTransactionManager#getTransaction(org.springframework.transaction.TransactionDefinition) */ - public MultiTransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { + public MultiTransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException { MultiTransactionStatus mts = new MultiTransactionStatus(transactionManagers.get(0)); + if (definition == null) { + return mts; + } + if (!synchronizationManager.isSynchronizationActive()) { synchronizationManager.initSynchronization(); mts.setNewSynchonization(); diff --git a/src/main/java/org/springframework/data/util/NullableUtils.java b/src/main/java/org/springframework/data/util/NullableUtils.java index 97a32b411..dc47e6cee 100644 --- a/src/main/java/org/springframework/data/util/NullableUtils.java +++ b/src/main/java/org/springframework/data/util/NullableUtils.java @@ -262,7 +262,7 @@ public class NullableUtils { .collect(Collectors.toSet()); } - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "rawtypes" }) private static Optional> findClass(String className) { try { diff --git a/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java b/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java index 73c9e7c53..799d04257 100644 --- a/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java +++ b/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java @@ -141,7 +141,7 @@ public class SpringDataWebConfiguration implements WebMvcConfigurer, BeanClassLo argumentResolvers.add(pageableResolver()); ProxyingHandlerMethodArgumentResolver resolver = new ProxyingHandlerMethodArgumentResolver( - getRequiredConversionService()); + conversionService.getObject()); resolver.setBeanFactory(context); forwardBeanClassLoader(resolver); @@ -180,17 +180,6 @@ public class SpringDataWebConfiguration implements WebMvcConfigurer, BeanClassLo sortResolverCustomizer.ifPresent(c -> c.customize(sortResolver)); } - private ConversionService getRequiredConversionService() { - - ConversionService conversionService = this.conversionService.getObject(); - - if (conversionService == null) { - throw new IllegalStateException("No ConversionService configured!"); - } - - return conversionService; - } - private void forwardBeanClassLoader(BeanClassLoaderAware target) { if (beanClassLoader != null) { diff --git a/src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolver.java b/src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolver.java index fe97d48d1..272f0397f 100644 --- a/src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolver.java +++ b/src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolver.java @@ -90,6 +90,7 @@ public class QuerydslPredicateArgumentResolver implements HandlerMethodArgumentR * (non-Javadoc) * @see org.springframework.web.method.support.HandlerMethodArgumentResolver#resolveArgument(org.springframework.core.MethodParameter, org.springframework.web.method.support.ModelAndViewContainer, org.springframework.web.context.request.NativeWebRequest, org.springframework.web.bind.support.WebDataBinderFactory) */ + @Nullable @Override public Predicate resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception { @@ -149,6 +150,10 @@ public class QuerydslPredicateArgumentResolver implements HandlerMethodArgumentR TypeInformation actualType = source.getActualType(); + if (actualType == null) { + throw new IllegalArgumentException(String.format("Could not determine domain type from %s!", source)); + } + if (source != actualType) { return detectDomainType(actualType); }