diff --git a/pom.xml b/pom.xml index 2ba13c3c9..51ffae761 100644 --- a/pom.xml +++ b/pom.xml @@ -495,6 +495,7 @@ org.slf4j:slf4j-api:*:*:compile org.slf4j:slf4j-log4j12:*:*:compile junit:junit:*:*:* + javax.annotation:javax.annotation-api:*:*:* false diff --git a/querydsl-apt/pom.xml b/querydsl-apt/pom.xml index a0683519c..9c5379e86 100644 --- a/querydsl-apt/pom.xml +++ b/querydsl-apt/pom.xml @@ -122,6 +122,19 @@ junit-jupiter test + + + com.google.testing.compile + compile-testing + 0.21.0 + test + + + junit + junit + + + diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/TypeElementHandler.java b/querydsl-apt/src/main/java/com/querydsl/apt/TypeElementHandler.java index e49084420..94782792d 100644 --- a/querydsl-apt/src/main/java/com/querydsl/apt/TypeElementHandler.java +++ b/querydsl-apt/src/main/java/com/querydsl/apt/TypeElementHandler.java @@ -172,7 +172,9 @@ private Property toProperty( inits = Arrays.asList(annotations.getAnnotation(QueryInit.class).value()); } - return new Property(entityType, name, propertyType, inits); + Property props = new Property(entityType, name, propertyType, inits); + Arrays.stream(annotations.getAnnotations()).forEach(props::addAnnotation); + return props; } public EntityType handleProjectionType(TypeElement e, boolean onlyAnnotatedConstructors) { diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/ArrayExtTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ArrayExtTest.java index 52d39715e..b46839250 100644 --- a/querydsl-apt/src/test/java/com/querydsl/apt/domain/ArrayExtTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ArrayExtTest.java @@ -39,39 +39,39 @@ public static class BinaryFile { @Test public void binaryFile_contentPart() { - assertThat(binaryFile.contentPart.getClass()).isEqualTo(ArrayPath.class); + assertThat(binaryFile.contentPart).isInstanceOf(ArrayPath.class); assertThat(binaryFile.contentPart.getType()).isEqualTo(byte[].class); } @Test public void binaryFile_list() { - assertThat(binaryFile.list.getClass()).isEqualTo(ListPath.class); + assertThat(binaryFile.list).isInstanceOf(ListPath.class); assertThat(binaryFile.list.getType()).isEqualTo(List.class); assertThat(binaryFile.list.getParameter(0)).isEqualTo(byte[].class); - assertThat(binaryFile.list.get(0).getClass()).isEqualTo(SimplePath.class); + assertThat(binaryFile.list.get(0)).isInstanceOf(SimplePath.class); assertThat(binaryFile.list.get(0).getType()).isEqualTo(byte[].class); } @Test public void binaryFile_map1() { - assertThat(binaryFile.map1.getClass()).isEqualTo(MapPath.class); + assertThat(binaryFile.map1).isInstanceOf(MapPath.class); assertThat(binaryFile.map1.getType()).isEqualTo(Map.class); assertThat(binaryFile.map1.getParameter(0)).isEqualTo(String.class); assertThat(binaryFile.map1.getParameter(1)).isEqualTo(byte[].class); - assertThat(binaryFile.map1.get("").getClass()).isEqualTo(SimplePath.class); + assertThat(binaryFile.map1.get("")).isInstanceOf(SimplePath.class); assertThat(binaryFile.map1.get("").getType()).isEqualTo(byte[].class); } @Test public void binaryFile_map2() { - assertThat(binaryFile.map2.getClass()).isEqualTo(MapPath.class); + assertThat(binaryFile.map2).isInstanceOf(MapPath.class); assertThat(binaryFile.map2.getType()).isEqualTo(Map.class); assertThat(binaryFile.map2.getParameter(0)).isEqualTo(byte[].class); assertThat(binaryFile.map2.getParameter(1)).isEqualTo(String.class); - assertThat(binaryFile.map2.get(new byte[0]).getClass()).isEqualTo(StringPath.class); + assertThat(binaryFile.map2.get(new byte[0])).isInstanceOf(StringPath.class); assertThat(binaryFile.map2.get(new byte[0]).getType()).isEqualTo(String.class); } } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/CollectionTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/CollectionTest.java index c65717a74..63f8c6bc1 100644 --- a/querydsl-apt/src/test/java/com/querydsl/apt/domain/CollectionTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/CollectionTest.java @@ -81,16 +81,16 @@ public void test() { // assertEquals(Object.class, // QMapWithUndefinedValueTest_Person.person.appData.getParameter(1)); - assertThat(QCollectionTest_Classes.classes.map1.getClass()).isEqualTo(MapPath.class); - assertThat(QCollectionTest_Classes.classes.map2.getClass()).isEqualTo(MapPath.class); - assertThat(QCollectionTest_Classes.classes.map3.getClass()).isEqualTo(MapPath.class); + assertThat(QCollectionTest_Classes.classes.map1).isInstanceOf(MapPath.class); + assertThat(QCollectionTest_Classes.classes.map2).isInstanceOf(MapPath.class); + assertThat(QCollectionTest_Classes.classes.map3).isInstanceOf(MapPath.class); - assertThat(QCollectionTest_Classes.classes.list1.getClass()).isEqualTo(ListPath.class); - assertThat(QCollectionTest_Classes.classes.list2.getClass()).isEqualTo(ListPath.class); - assertThat(QCollectionTest_Classes.classes.list3.getClass()).isEqualTo(ListPath.class); + assertThat(QCollectionTest_Classes.classes.list1).isInstanceOf(ListPath.class); + assertThat(QCollectionTest_Classes.classes.list2).isInstanceOf(ListPath.class); + assertThat(QCollectionTest_Classes.classes.list3).isInstanceOf(ListPath.class); - assertThat(QCollectionTest_Classes.classes.set1.getClass()).isEqualTo(SetPath.class); - assertThat(QCollectionTest_Classes.classes.set2.getClass()).isEqualTo(SetPath.class); - assertThat(QCollectionTest_Classes.classes.set3.getClass()).isEqualTo(SetPath.class); + assertThat(QCollectionTest_Classes.classes.set1).isInstanceOf(SetPath.class); + assertThat(QCollectionTest_Classes.classes.set2).isInstanceOf(SetPath.class); + assertThat(QCollectionTest_Classes.classes.set3).isInstanceOf(SetPath.class); } } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/ElementCollectionTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ElementCollectionTest.java new file mode 100644 index 000000000..a08efbe04 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ElementCollectionTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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 + * http://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. + */ +package com.querydsl.apt.domain; + +import static com.google.testing.compile.CompilationSubject.assertThat; +import static com.google.testing.compile.Compiler.javac; +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.testing.compile.Compilation; +import com.google.testing.compile.JavaFileObjects; +import com.querydsl.apt.jpa.JPAAnnotationProcessor; +import com.querydsl.core.types.dsl.ElementCollectionPath; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Entity; +import java.io.File; +import java.util.Collection; +import org.junit.Test; + +public class ElementCollectionTest { + + @Entity + public static class EntityClass { + + @ElementCollection Collection collectionOfElements; + } + + private final File main = new File("src/test/java/").getAbsoluteFile(); + + @Test + public void properties() { + assertThat(QElementCollectionTest_EntityClass.entityClass.collectionOfElements).isNotNull(); + assertThat(QElementCollectionTest_EntityClass.entityClass.collectionOfElements) + .isInstanceOf(ElementCollectionPath.class); + } + + @Test + public void test() throws Exception { + final Compilation compilation = + javac() + .withProcessors(new JPAAnnotationProcessor()) + .withClasspathFrom(this.getClass().getClassLoader()) + .compile( + JavaFileObjects.forResource( + new File(main, "com/querydsl/apt/domain/ElementCollectionTest.java") + .toURI() + .toURL())); + assertThat(compilation).succeeded(); + assertThat(compilation) + .generatedSourceFile("com.querydsl.apt.domain.QElementCollectionTest_EntityClass") + .contentsAsUtf8String() + .contains("createElementCollection(\"collectionOfElements\""); + } +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddableInterfaceTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddableInterfaceTest.java index 38dc1be92..eeec935ed 100644 --- a/querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddableInterfaceTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddableInterfaceTest.java @@ -13,11 +13,18 @@ */ package com.querydsl.apt.domain; +import static com.google.testing.compile.CompilationSubject.assertThat; +import static com.google.testing.compile.Compiler.javac; import static org.assertj.core.api.Assertions.assertThat; +import com.google.testing.compile.Compilation; +import com.google.testing.compile.JavaFileObjects; +import com.querydsl.apt.jpa.JPAAnnotationProcessor; +import com.querydsl.core.types.dsl.ElementCollectionPath; import jakarta.persistence.ElementCollection; import jakarta.persistence.Embeddable; import jakarta.persistence.Entity; +import java.io.File; import java.util.Collection; import org.junit.Test; @@ -47,8 +54,10 @@ public String getName() { @Test public void type() { - assertThat(QEmbeddableInterfaceTest_EntityClass.entityClass.children.any().getClass()) - .isEqualTo(QEmbeddableInterfaceTest_EmbeddableInterface.class); + assertThat(QEmbeddableInterfaceTest_EntityClass.entityClass.children.any()) + .isInstanceOf(QEmbeddableInterfaceTest_EmbeddableInterface.class); + assertThat(QEmbeddableInterfaceTest_EntityClass.entityClass.children) + .isInstanceOf(ElementCollectionPath.class); } @Test @@ -56,4 +65,24 @@ public void properties() { assertThat(QEmbeddableInterfaceTest_EmbeddableInterface.embeddableInterface.name).isNotNull(); assertThat(QEmbeddableInterfaceTest_EmbeddableClass.embeddableClass.name).isNotNull(); } + + private final File main = new File("src/test/java/").getAbsoluteFile(); + + @Test + public void test() throws Exception { + final Compilation compilation = + javac() + .withProcessors(new JPAAnnotationProcessor()) + .withClasspathFrom(this.getClass().getClassLoader()) + .compile( + JavaFileObjects.forResource( + new File(main, "com/querydsl/apt/domain/EmbeddableInterfaceTest.java") + .toURI() + .toURL())); + assertThat(compilation).succeeded(); + assertThat(compilation) + .generatedSourceFile("com.querydsl.apt.domain.QEmbeddableInterfaceTest_EntityClass") + .contentsAsUtf8String() + .contains("createElementCollection(\"children\""); + } } diff --git a/querydsl-codegen/pom.xml b/querydsl-codegen/pom.xml index 6c02cb93a..aef1b7357 100644 --- a/querydsl-codegen/pom.xml +++ b/querydsl-codegen/pom.xml @@ -47,10 +47,10 @@ test-jar test + - javax.annotation - javax.annotation-api - 1.3.2 + jakarta.persistence + jakarta.persistence-api provided diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultEntitySerializer.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultEntitySerializer.java index da706a897..e35857675 100644 --- a/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultEntitySerializer.java +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultEntitySerializer.java @@ -21,6 +21,7 @@ import com.querydsl.core.types.dsl.*; import jakarta.inject.Inject; import jakarta.inject.Named; +import jakarta.persistence.ElementCollection; import java.io.IOException; import java.lang.annotation.Annotation; import java.util.*; @@ -900,6 +901,9 @@ protected void serializeProperties(EntityType model, SerializerConfig config, Co localRawName = writer.getRawName(property.getParameter(0)); queryType = typeMappings.getPathType(property.getParameter(0), model, true); + String createCollection = + isElementCollection(property) ? "createElementCollection" : "createCollection"; + serialize( model, property, @@ -910,7 +914,8 @@ CollectionPath.class, getRaw(property.getParameter(0)), genericQueryType), + genericKey + COMMA + writer.getGenericName(true, genericQueryType) - + ">createCollection", + + ">" + + createCollection, writer.getClassConstant(localRawName), writer.getClassConstant(writer.getRawName(queryType)), inits); @@ -923,6 +928,8 @@ CollectionPath.class, getRaw(property.getParameter(0)), genericQueryType), localRawName = writer.getRawName(property.getParameter(0)); queryType = typeMappings.getPathType(property.getParameter(0), model, true); + String createSet = isElementCollection(property) ? "createElementSet" : "createSet"; + serialize( model, property, @@ -932,7 +939,8 @@ CollectionPath.class, getRaw(property.getParameter(0)), genericQueryType), + genericKey + COMMA + writer.getGenericName(true, genericQueryType) - + ">createSet", + + ">" + + createSet, writer.getClassConstant(localRawName), writer.getClassConstant(writer.getRawName(queryType)), inits); @@ -945,6 +953,8 @@ CollectionPath.class, getRaw(property.getParameter(0)), genericQueryType), localRawName = writer.getRawName(property.getParameter(0)); queryType = typeMappings.getPathType(property.getParameter(0), model, true); + String createList = isElementCollection(property) ? "createElementList" : "createList"; + serialize( model, property, @@ -954,7 +964,8 @@ CollectionPath.class, getRaw(property.getParameter(0)), genericQueryType), + genericKey + COMMA + writer.getGenericName(true, genericQueryType) - + ">createList", + + ">" + + createList, writer.getClassConstant(localRawName), writer.getClassConstant(writer.getRawName(queryType)), inits); @@ -997,6 +1008,15 @@ CollectionPath.class, getRaw(property.getParameter(0)), genericQueryType), } } + private boolean isElementCollection(Property property) { + try { + Class.forName("jakarta.persistence.ElementCollection"); + return property.getAnnotation(ElementCollection.class) == null; + } catch (ClassNotFoundException e) { + return false; + } + } + private String getInits(Property property) { if (!property.getInits().isEmpty()) { return "INITS.get(\"" + property.getName() + "\")"; diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/ElementCollectionImpl.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/ElementCollectionImpl.java new file mode 100644 index 000000000..8cd5691cd --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/ElementCollectionImpl.java @@ -0,0 +1,23 @@ +package com.querydsl.codegen; + +import jakarta.persistence.ElementCollection; +import jakarta.persistence.FetchType; +import java.lang.annotation.Annotation; + +public class ElementCollectionImpl implements ElementCollection { + + @Override + public Class annotationType() { + return ElementCollection.class; + } + + @Override + public Class targetClass() { + return null; + } + + @Override + public FetchType fetch() { + return null; + } +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/EntitySerializerTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/EntitySerializerTest.java index 6a97a50cc..227581c66 100644 --- a/querydsl-codegen/src/test/java/com/querydsl/codegen/EntitySerializerTest.java +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/EntitySerializerTest.java @@ -24,6 +24,7 @@ import java.util.Collections; import java.util.Date; import java.util.EnumMap; +import java.util.List; import java.util.Map; import org.junit.Test; @@ -183,6 +184,14 @@ public void properties() throws IOException { new Property(entityType, "s", new ClassType(TypeCategory.STRING, String.class))); entityType.addProperty( new Property(entityType, "t", new ClassType(TypeCategory.TIME, Time.class))); + Property property = + new Property( + entityType, + "cl", + new ClassType(TypeCategory.LIST, List.class, new ClassType(String.class))); + property.addAnnotation(new ElementCollectionImpl()); + entityType.addProperty(property); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); diff --git a/querydsl-core/src/main/java/com/querydsl/core/types/dsl/BeanPath.java b/querydsl-core/src/main/java/com/querydsl/core/types/dsl/BeanPath.java index e9e90d2b6..4c4ea0757 100644 --- a/querydsl-core/src/main/java/com/querydsl/core/types/dsl/BeanPath.java +++ b/querydsl-core/src/main/java/com/querydsl/core/types/dsl/BeanPath.java @@ -202,6 +202,21 @@ protected DateTimePath createDateTime( return add(new DateTimePath((Class) type, forProperty(property))); } + /** + * Create a new Collection typed path + * + * @param + * @param property property name + * @param type property type + * @return property path + */ + @SuppressWarnings("unchecked") + protected > CollectionPath createElementCollection( + String property, Class type, Class queryType, PathInits inits) { + return add( + new ElementCollectionPath(type, (Class) queryType, forProperty(property), inits)); + } + /** * Create a new List typed path * @@ -213,9 +228,23 @@ protected DateTimePath createDateTime( * @return property path */ @SuppressWarnings("unchecked") - protected > ListPath createList( + protected > ListPath createElementList( String property, Class type, Class queryType, PathInits inits) { - return add(new ListPath(type, (Class) queryType, forProperty(property), inits)); + return add(new ElementListPath(type, (Class) queryType, forProperty(property), inits)); + } + + /** + * Create a new Set typed path + * + * @param + * @param property property name + * @param type property type + * @return property path + */ + @SuppressWarnings("unchecked") + protected > SetPath createElementSet( + String property, Class type, Class queryType, PathInits inits) { + return add(new ElementSetPath(type, (Class) queryType, forProperty(property), inits)); } /** @@ -300,6 +329,22 @@ protected TimePath createTime(String property, Class((Class) type, forProperty(property))); } + /** + * Create a new List typed path + * + * @param + * @param + * @param property property name + * @param type property type + * @param queryType expression type + * @return property path + */ + @SuppressWarnings("unchecked") + protected > ListPath createList( + String property, Class type, Class queryType, PathInits inits) { + return add(new ListPath(type, (Class) queryType, forProperty(property), inits)); + } + protected PathMetadata forProperty(String property) { return PathMetadataFactory.forProperty(this, property); } diff --git a/querydsl-core/src/main/java/com/querydsl/core/types/dsl/ElementCollectionPath.java b/querydsl-core/src/main/java/com/querydsl/core/types/dsl/ElementCollectionPath.java new file mode 100644 index 000000000..438652bb7 --- /dev/null +++ b/querydsl-core/src/main/java/com/querydsl/core/types/dsl/ElementCollectionPath.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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 + * http://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. + */ +package com.querydsl.core.types.dsl; + +import com.querydsl.core.types.*; + +/** + * {@code ElementCollectionPath} represents collection paths annotated with {@link + * javax.persistence.ElementCollection} + * + * @param component type + * @param component query type + */ +public class ElementCollectionPath> + extends CollectionPath { + + public ElementCollectionPath( + Class type, Class queryType, Path parent, String property) { + super(type, queryType, parent, property); + } + + public ElementCollectionPath( + Class type, Class queryType, PathMetadata metadata, PathInits inits) { + super(type, queryType, metadata, inits); + } + + public ElementCollectionPath(Class type, Class queryType, PathMetadata metadata) { + super(type, queryType, metadata); + } + + public ElementCollectionPath(Class type, Class queryType, String variable) { + super(type, queryType, variable); + } +} diff --git a/querydsl-core/src/main/java/com/querydsl/core/types/dsl/ElementListPath.java b/querydsl-core/src/main/java/com/querydsl/core/types/dsl/ElementListPath.java new file mode 100644 index 000000000..eb6daafa6 --- /dev/null +++ b/querydsl-core/src/main/java/com/querydsl/core/types/dsl/ElementListPath.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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 + * http://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. + */ +package com.querydsl.core.types.dsl; + +import com.querydsl.core.types.*; + +/** + * {@code ElementListPath} represents list paths annotated with {@link + * javax.persistence.ElementCollection} + * + * @param component type + * @param component query type + */ +public class ElementListPath> extends ListPath { + + public ElementListPath( + Class type, Class queryType, Path parent, String property) { + super(type, queryType, parent, property); + } + + public ElementListPath( + Class type, Class queryType, PathMetadata metadata, PathInits inits) { + super(type, queryType, metadata, inits); + } + + public ElementListPath(Class type, Class queryType, PathMetadata metadata) { + super(type, queryType, metadata); + } + + public ElementListPath(Class type, Class queryType, String variable) { + super(type, queryType, variable); + } +} diff --git a/querydsl-core/src/main/java/com/querydsl/core/types/dsl/ElementSetPath.java b/querydsl-core/src/main/java/com/querydsl/core/types/dsl/ElementSetPath.java new file mode 100644 index 000000000..3c410e514 --- /dev/null +++ b/querydsl-core/src/main/java/com/querydsl/core/types/dsl/ElementSetPath.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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 + * http://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. + */ +package com.querydsl.core.types.dsl; + +import com.querydsl.core.types.*; + +/** + * {@code ElementSetPath} represents set paths annotated with {@link + * javax.persistence.ElementCollection} + * + * @param component type + * @param component query type + */ +public class ElementSetPath> extends SetPath { + + public ElementSetPath( + Class type, Class queryType, Path parent, String property) { + super(type, queryType, parent, property); + } + + public ElementSetPath( + Class type, Class queryType, PathMetadata metadata, PathInits inits) { + super(type, queryType, metadata, inits); + } + + public ElementSetPath(Class type, Class queryType, PathMetadata metadata) { + super(type, queryType, metadata); + } + + public ElementSetPath(Class type, Class queryType, String variable) { + super(type, queryType, variable); + } +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLSerializer.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLSerializer.java index de9cc9289..8de225132 100644 --- a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLSerializer.java +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLSerializer.java @@ -34,6 +34,7 @@ import com.querydsl.core.types.PathType; import com.querydsl.core.types.Predicate; import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.core.types.dsl.ElementCollectionPath; import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.util.MathUtils; import jakarta.persistence.Entity; @@ -471,8 +472,10 @@ protected void visitOperation( visitOperation(type, Ops.NOT_IN, args); } else if (operator == Ops.IN || operator == Ops.NOT_IN) { - if (args.get(1) instanceof Path) { + if (args.get(1) instanceof ElementCollectionPath) { visitAnyInPath(type, operator, args); + } else if (args.get(1) instanceof Path) { + super.visitOperation(type, operator, args); } else if (args.get(0) instanceof Path && args.get(1) instanceof Constant) { visitPathInCollection(type, operator, args); } else { diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPABase.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPABase.java index 8c5a0740a..6b9a5489b 100644 --- a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPABase.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPABase.java @@ -29,13 +29,14 @@ import com.querydsl.core.types.Expression; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.jpa.domain.*; import com.querydsl.jpa.domain.Cat; import com.querydsl.jpa.domain.Parent; import com.querydsl.jpa.domain.QCat; import com.querydsl.jpa.domain.QCatSummary; -import com.querydsl.jpa.domain.QChild; import com.querydsl.jpa.domain.QGroup; import com.querydsl.jpa.domain.QParent; +import com.querydsl.jpa.domain.UserRole; import com.querydsl.jpa.impl.JPADeleteClause; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.testutil.JPATestRunner; @@ -60,6 +61,7 @@ public class JPABase extends AbstractJPATest implements JPATest { private static final QCat cat = QCat.cat; + private static final QUser user = QUser.user; @Rule @ClassRule public static TestRule targetRule = new TargetRule(); @@ -330,4 +332,22 @@ public void shouldTransformWithGroupBy() { assertThat(transform).hasSize(1); } + + @Test + public void converterSet_anyEq() { + List rows = + query().from(user).select(user).where(user.roles.any().eq(UserRole.ADMIN)).fetch(); + for (User row : rows) { + assertThat(row).isNotNull(); + } + } + + @Test + public void converterSet_contains() { + List rows = + query().from(user).select(user).where(user.roles.contains(UserRole.ADMIN)).fetch(); + for (User row : rows) { + assertThat(row).isNotNull(); + } + } } diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPQLSerializerTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPQLSerializerTest.java index 84efbe696..810ad07f9 100644 --- a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPQLSerializerTest.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPQLSerializerTest.java @@ -209,7 +209,7 @@ public void where_in() { md.addWhere(user.roles.contains(UserRole.ADMIN)); serializer.serialize(md, false, null); assertThat(serializer.toString()) - .isEqualTo(""" + .isEqualToIgnoringWhitespace(""" select user from User user where ?1 in user.roles diff --git a/querydsl-sql-spatial/pom.xml b/querydsl-sql-spatial/pom.xml index 24d4babe8..6f8d3692e 100644 --- a/querydsl-sql-spatial/pom.xml +++ b/querydsl-sql-spatial/pom.xml @@ -172,13 +172,6 @@ 2.9.1 test - - - javax.annotation - javax.annotation-api - 1.3.2 - provided - diff --git a/querydsl-sql/pom.xml b/querydsl-sql/pom.xml index ed021447a..624b1c106 100644 --- a/querydsl-sql/pom.xml +++ b/querydsl-sql/pom.xml @@ -182,13 +182,6 @@ ${jmh.version} test - - - javax.annotation - javax.annotation-api - 1.3.2 - provided -