Browse Source

Polishing.

Use getPackageName() instead of getPackage().getName(), remove essentially duplicate tests and fix array type handling of Q types by using the arrays component type for assignability checks.

Original Pull Request: #3284
pull/3309/head
Christoph Strobl 7 months ago
parent
commit
f28a2c2052
No known key found for this signature in database
GPG Key ID: E6054036D0C37A4B
  1. 21
      src/main/java/org/springframework/data/util/QTypeContributor.java
  2. 23
      src/test/java/QTypeInDefaultPackage.java
  3. 62
      src/test/java/org/springframework/data/util/QTypeContributorUnitTests.java

21
src/main/java/org/springframework/data/util/QTypeContributor.java

@ -18,11 +18,11 @@ package org.springframework.data.util;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable; import org.jspecify.annotations.Nullable;
import org.springframework.aot.generate.GenerationContext; import org.springframework.aot.generate.GenerationContext;
import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.TypeReference; import org.springframework.aot.hint.TypeReference;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
/** /**
* @author Christoph Strobl * @author Christoph Strobl
@ -38,18 +38,20 @@ public class QTypeContributor {
Class<?> entityPathType = getEntityPathType(classLoader); Class<?> entityPathType = getEntityPathType(classLoader);
if (entityPathType == null) { if (entityPathType == null || type.isPrimitive()) {
return;
}
if (type.isPrimitive() || type.isArray()) {
return; return;
} }
String queryClassName = getQueryClassName(type); String queryClassName = getQueryClassName(type);
if (ClassUtils.isPresent(queryClassName, classLoader)) { if (ClassUtils.isPresent(queryClassName, classLoader)) {
if (ClassUtils.isAssignable(entityPathType, ClassUtils.forName(queryClassName, classLoader))) { Class<?> actualType = ClassUtils.forName(queryClassName, classLoader);
if (actualType.isArray()) {
actualType = actualType.getComponentType();
}
if (ClassUtils.isAssignable(entityPathType, actualType)) {
logger.debug("Registering Q type %s for %s."); logger.debug("Registering Q type %s for %s.");
context.getRuntimeHints().reflection().registerType(TypeReference.of(queryClassName), context.getRuntimeHints().reflection().registerType(TypeReference.of(queryClassName),
@ -84,7 +86,10 @@ public class QTypeContributor {
private static String getQueryClassName(Class<?> domainClass) { private static String getQueryClassName(Class<?> domainClass) {
String simpleClassName = ClassUtils.getShortName(domainClass); String simpleClassName = ClassUtils.getShortName(domainClass);
String pkgName = domainClass.getPackage().getName(); String pkgName = domainClass.getPackageName();
if (ObjectUtils.isEmpty(pkgName)) {
return String.format("Q%s%s", getClassBase(simpleClassName), domainClass.getSimpleName());
}
return String.format("%s.Q%s%s", pkgName, getClassBase(simpleClassName), domainClass.getSimpleName()); return String.format("%s.Q%s%s", pkgName, getClassBase(simpleClassName), domainClass.getSimpleName());
} }

23
src/test/java/QTypeInDefaultPackage.java

@ -0,0 +1,23 @@
/*
* Copyright 2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Dummy type looking like a QueryDSL Generated one but its not - does not extend the
* {@link com.querydsl.core.types.dsl.EntityPathBase})
*
* @author Christoph Strobl
*/
public class QTypeInDefaultPackage {}

62
src/test/java/org/springframework/data/util/QTypeContributorUnitTests.java

@ -15,7 +15,12 @@
*/ */
package org.springframework.data.util; package org.springframework.data.util;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatNoException;
import java.net.URLClassLoader;
import java.util.HashSet;
import java.util.Set;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.aot.generate.ClassNameGenerator; import org.springframework.aot.generate.ClassNameGenerator;
@ -26,7 +31,6 @@ import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.data.aot.sample.ConfigWithQuerydslPredicateExecutor.Person; import org.springframework.data.aot.sample.ConfigWithQuerydslPredicateExecutor.Person;
import org.springframework.data.aot.sample.QConfigWithQuerydslPredicateExecutor_Person; import org.springframework.data.aot.sample.QConfigWithQuerydslPredicateExecutor_Person;
import org.springframework.data.classloadersupport.HidingClassLoader; import org.springframework.data.classloadersupport.HidingClassLoader;
import org.springframework.data.querydsl.User;
import org.springframework.javapoet.ClassName; import org.springframework.javapoet.ClassName;
import com.querydsl.core.types.EntityPath; import com.querydsl.core.types.EntityPath;
@ -34,6 +38,7 @@ import com.querydsl.core.types.EntityPath;
/** /**
* Unit tests for {@link QTypeContributor}. * Unit tests for {@link QTypeContributor}.
* *
* @author Christoph Strobl
* @author ckdgus08 * @author ckdgus08
*/ */
class QTypeContributorUnitTests { class QTypeContributorUnitTests {
@ -75,8 +80,8 @@ class QTypeContributorUnitTests {
RuntimeHintsPredicates.reflection().onType(QConfigWithQuerydslPredicateExecutor_Person.class).negate()); RuntimeHintsPredicates.reflection().onType(QConfigWithQuerydslPredicateExecutor_Person.class).negate());
} }
@Test // DATAMONGO-4958 @Test // GH-3284
void doesNotAddQTypeHintForArrayType() { void addsQTypeHintForArrayType() {
GenerationContext generationContext = new DefaultGenerationContext( GenerationContext generationContext = new DefaultGenerationContext(
new ClassNameGenerator(ClassName.get(this.getClass())), new InMemoryGeneratedFiles()); new ClassNameGenerator(ClassName.get(this.getClass())), new InMemoryGeneratedFiles());
@ -85,48 +90,47 @@ class QTypeContributorUnitTests {
assertThat(generationContext.getRuntimeHints()).matches( assertThat(generationContext.getRuntimeHints()).matches(
RuntimeHintsPredicates.reflection().onType(QConfigWithQuerydslPredicateExecutor_Person.class).negate()); RuntimeHintsPredicates.reflection().onType(QConfigWithQuerydslPredicateExecutor_Person.class).negate());
assertThat(generationContext.getRuntimeHints()).matches( assertThat(generationContext.getRuntimeHints())
RuntimeHintsPredicates.reflection().onType(QConfigWithQuerydslPredicateExecutor_Person[].class).negate()); .matches(RuntimeHintsPredicates.reflection().onType(QConfigWithQuerydslPredicateExecutor_Person[].class));
} }
@Test // DATAMONGO-4958 @Test // GH-3284
void addsQTypeHintForQUserType() { void doesNotAddQTypeHintForPrimitiveType() {
GenerationContext generationContext = new DefaultGenerationContext( GenerationContext generationContext = new DefaultGenerationContext(
new ClassNameGenerator(ClassName.get(this.getClass())), new InMemoryGeneratedFiles()); new ClassNameGenerator(ClassName.get(this.getClass())), new InMemoryGeneratedFiles());
QTypeContributor.contributeEntityPath(User.class, generationContext, getClass().getClassLoader()); QTypeContributor.contributeEntityPath(int.class, generationContext, getClass().getClassLoader());
var qUserHintCount = generationContext.getRuntimeHints().reflection().typeHints() assertThat(generationContext.getRuntimeHints().reflection().typeHints()).isEmpty();
.filter(hint -> hint.getType().getName().equals("org.springframework.data.querydsl.QUser"))
.count();
assertThat(qUserHintCount).isEqualTo(1);
} }
@Test // DATAMONGO-4958 @Test // GH-3284
void doesNotAddQTypeHintForQUserArrayType() { void doesNotFailForTypeInDefaultPackage() throws Exception {
GenerationContext generationContext = new DefaultGenerationContext( GenerationContext generationContext = new DefaultGenerationContext(
new ClassNameGenerator(ClassName.get(this.getClass())), new InMemoryGeneratedFiles()); new ClassNameGenerator(ClassName.get(this.getClass())), new InMemoryGeneratedFiles());
var classLoader = getClass().getClassLoader();
QTypeContributor.contributeEntityPath(User[].class, generationContext, classLoader); class CapturingClassLoader extends ClassLoader {
assertThat(generationContext.getRuntimeHints().reflection().typeHints()).isEmpty(); final Set<String> lookups = new HashSet<>(10);
var qUserHintCount = generationContext.getRuntimeHints().reflection().typeHints()
.filter(hint -> hint.getType().getName().equals("org.springframework.data.querydsl.QUser"))
.count();
assertThat(qUserHintCount).isEqualTo(0);
}
@Test // DATAMONGO-4958 CapturingClassLoader() {
void doesNotAddQTypeHintForPrimitiveType() { super(URLClassLoader.getSystemClassLoader());
}
GenerationContext generationContext = new DefaultGenerationContext( @Override
new ClassNameGenerator(ClassName.get(this.getClass())), new InMemoryGeneratedFiles()); public Class<?> loadClass(String name) throws ClassNotFoundException {
lookups.add(name);
return super.loadClass(name);
}
}
QTypeContributor.contributeEntityPath(int.class, generationContext, getClass().getClassLoader()); CapturingClassLoader classLoaderToUse = new CapturingClassLoader();
assertThat(generationContext.getRuntimeHints().reflection().typeHints()).isEmpty(); var typeInDefaultPackage = Class.forName("TypeInDefaultPackage");
assertThatNoException().isThrownBy(
() -> QTypeContributor.contributeEntityPath(typeInDefaultPackage, generationContext, classLoaderToUse));
assertThat(classLoaderToUse.lookups).contains("QTypeInDefaultPackage");
} }
} }

Loading…
Cancel
Save