Skip to content

Commit f28a2c2

Browse files
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
1 parent 3499012 commit f28a2c2

File tree

3 files changed

+69
-37
lines changed

3 files changed

+69
-37
lines changed

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
import org.apache.commons.logging.Log;
1919
import org.apache.commons.logging.LogFactory;
2020
import org.jspecify.annotations.Nullable;
21-
2221
import org.springframework.aot.generate.GenerationContext;
2322
import org.springframework.aot.hint.MemberCategory;
2423
import org.springframework.aot.hint.TypeReference;
2524
import org.springframework.util.ClassUtils;
25+
import org.springframework.util.ObjectUtils;
2626

2727
/**
2828
* @author Christoph Strobl
@@ -38,18 +38,20 @@ public static void contributeEntityPath(Class<?> type, GenerationContext context
3838

3939
Class<?> entityPathType = getEntityPathType(classLoader);
4040

41-
if (entityPathType == null) {
42-
return;
43-
}
44-
45-
if (type.isPrimitive() || type.isArray()) {
41+
if (entityPathType == null || type.isPrimitive()) {
4642
return;
4743
}
4844

4945
String queryClassName = getQueryClassName(type);
46+
5047
if (ClassUtils.isPresent(queryClassName, classLoader)) {
5148

52-
if (ClassUtils.isAssignable(entityPathType, ClassUtils.forName(queryClassName, classLoader))) {
49+
Class<?> actualType = ClassUtils.forName(queryClassName, classLoader);
50+
if (actualType.isArray()) {
51+
actualType = actualType.getComponentType();
52+
}
53+
54+
if (ClassUtils.isAssignable(entityPathType, actualType)) {
5355

5456
logger.debug("Registering Q type %s for %s.");
5557
context.getRuntimeHints().reflection().registerType(TypeReference.of(queryClassName),
@@ -84,7 +86,10 @@ public static void contributeEntityPath(Class<?> type, GenerationContext context
8486
private static String getQueryClassName(Class<?> domainClass) {
8587

8688
String simpleClassName = ClassUtils.getShortName(domainClass);
87-
String pkgName = domainClass.getPackage().getName();
89+
String pkgName = domainClass.getPackageName();
90+
if (ObjectUtils.isEmpty(pkgName)) {
91+
return String.format("Q%s%s", getClassBase(simpleClassName), domainClass.getSimpleName());
92+
}
8893

8994
return String.format("%s.Q%s%s", pkgName, getClassBase(simpleClassName), domainClass.getSimpleName());
9095
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* Dummy type looking like a QueryDSL Generated one but its not - does not extend the
19+
* {@link com.querydsl.core.types.dsl.EntityPathBase})
20+
*
21+
* @author Christoph Strobl
22+
*/
23+
public class QTypeInDefaultPackage {}

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

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@
1515
*/
1616
package org.springframework.data.util;
1717

18-
import static org.assertj.core.api.Assertions.*;
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
import static org.assertj.core.api.Assertions.assertThatNoException;
20+
21+
import java.net.URLClassLoader;
22+
import java.util.HashSet;
23+
import java.util.Set;
1924

2025
import org.junit.jupiter.api.Test;
2126
import org.springframework.aot.generate.ClassNameGenerator;
@@ -26,14 +31,14 @@
2631
import org.springframework.data.aot.sample.ConfigWithQuerydslPredicateExecutor.Person;
2732
import org.springframework.data.aot.sample.QConfigWithQuerydslPredicateExecutor_Person;
2833
import org.springframework.data.classloadersupport.HidingClassLoader;
29-
import org.springframework.data.querydsl.User;
3034
import org.springframework.javapoet.ClassName;
3135

3236
import com.querydsl.core.types.EntityPath;
3337

3438
/**
3539
* Unit tests for {@link QTypeContributor}.
3640
*
41+
* @author Christoph Strobl
3742
* @author ckdgus08
3843
*/
3944
class QTypeContributorUnitTests {
@@ -75,8 +80,8 @@ void doesNotAddQTypeHintIfQuerydslNotPresent() {
7580
RuntimeHintsPredicates.reflection().onType(QConfigWithQuerydslPredicateExecutor_Person.class).negate());
7681
}
7782

78-
@Test // DATAMONGO-4958
79-
void doesNotAddQTypeHintForArrayType() {
83+
@Test // GH-3284
84+
void addsQTypeHintForArrayType() {
8085

8186
GenerationContext generationContext = new DefaultGenerationContext(
8287
new ClassNameGenerator(ClassName.get(this.getClass())), new InMemoryGeneratedFiles());
@@ -85,48 +90,47 @@ void doesNotAddQTypeHintForArrayType() {
8590

8691
assertThat(generationContext.getRuntimeHints()).matches(
8792
RuntimeHintsPredicates.reflection().onType(QConfigWithQuerydslPredicateExecutor_Person.class).negate());
88-
assertThat(generationContext.getRuntimeHints()).matches(
89-
RuntimeHintsPredicates.reflection().onType(QConfigWithQuerydslPredicateExecutor_Person[].class).negate());
93+
assertThat(generationContext.getRuntimeHints())
94+
.matches(RuntimeHintsPredicates.reflection().onType(QConfigWithQuerydslPredicateExecutor_Person[].class));
9095
}
9196

92-
@Test // DATAMONGO-4958
93-
void addsQTypeHintForQUserType() {
97+
@Test // GH-3284
98+
void doesNotAddQTypeHintForPrimitiveType() {
9499

95100
GenerationContext generationContext = new DefaultGenerationContext(
96101
new ClassNameGenerator(ClassName.get(this.getClass())), new InMemoryGeneratedFiles());
97102

98-
QTypeContributor.contributeEntityPath(User.class, generationContext, getClass().getClassLoader());
103+
QTypeContributor.contributeEntityPath(int.class, generationContext, getClass().getClassLoader());
99104

100-
var qUserHintCount = generationContext.getRuntimeHints().reflection().typeHints()
101-
.filter(hint -> hint.getType().getName().equals("org.springframework.data.querydsl.QUser"))
102-
.count();
103-
assertThat(qUserHintCount).isEqualTo(1);
105+
assertThat(generationContext.getRuntimeHints().reflection().typeHints()).isEmpty();
104106
}
105107

106-
@Test // DATAMONGO-4958
107-
void doesNotAddQTypeHintForQUserArrayType() {
108+
@Test // GH-3284
109+
void doesNotFailForTypeInDefaultPackage() throws Exception {
108110

109111
GenerationContext generationContext = new DefaultGenerationContext(
110112
new ClassNameGenerator(ClassName.get(this.getClass())), new InMemoryGeneratedFiles());
111-
var classLoader = getClass().getClassLoader();
112113

113-
QTypeContributor.contributeEntityPath(User[].class, generationContext, classLoader);
114+
class CapturingClassLoader extends ClassLoader {
114115

115-
assertThat(generationContext.getRuntimeHints().reflection().typeHints()).isEmpty();
116-
var qUserHintCount = generationContext.getRuntimeHints().reflection().typeHints()
117-
.filter(hint -> hint.getType().getName().equals("org.springframework.data.querydsl.QUser"))
118-
.count();
119-
assertThat(qUserHintCount).isEqualTo(0);
120-
}
116+
final Set<String> lookups = new HashSet<>(10);
121117

122-
@Test // DATAMONGO-4958
123-
void doesNotAddQTypeHintForPrimitiveType() {
118+
CapturingClassLoader() {
119+
super(URLClassLoader.getSystemClassLoader());
120+
}
124121

125-
GenerationContext generationContext = new DefaultGenerationContext(
126-
new ClassNameGenerator(ClassName.get(this.getClass())), new InMemoryGeneratedFiles());
122+
@Override
123+
public Class<?> loadClass(String name) throws ClassNotFoundException {
124+
lookups.add(name);
125+
return super.loadClass(name);
126+
}
127+
}
127128

128-
QTypeContributor.contributeEntityPath(int.class, generationContext, getClass().getClassLoader());
129+
CapturingClassLoader classLoaderToUse = new CapturingClassLoader();
129130

130-
assertThat(generationContext.getRuntimeHints().reflection().typeHints()).isEmpty();
131+
var typeInDefaultPackage = Class.forName("TypeInDefaultPackage");
132+
assertThatNoException().isThrownBy(
133+
() -> QTypeContributor.contributeEntityPath(typeInDefaultPackage, generationContext, classLoaderToUse));
134+
assertThat(classLoaderToUse.lookups).contains("QTypeInDefaultPackage");
131135
}
132136
}

0 commit comments

Comments
 (0)