Skip to content

Commit b046887

Browse files
authored
Fix KSP enum codegen with Convert annotation (#1411)
1 parent b43432f commit b046887

File tree

5 files changed

+78
-3
lines changed

5 files changed

+78
-3
lines changed

querydsl-examples/querydsl-example-ksp-codegen/src/main/kotlin/com/querydsl/example/ksp/Bear.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.querydsl.example.ksp
22

33
import com.querydsl.core.annotations.QueryProjection
4+
import jakarta.persistence.Convert
45
import jakarta.persistence.Entity
56
import jakarta.persistence.Id
67

@@ -9,7 +10,9 @@ class Bear(
910
@Id
1011
val id: Int,
1112
val name: String,
12-
val location: String
13+
val location: String,
14+
@Convert(converter = BearSpeciesConverter::class)
15+
val species: BearSpecies?
1316
)
1417

1518
class BearSimplifiedProjection @QueryProjection constructor(
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.querydsl.example.ksp
2+
3+
enum class BearSpecies {
4+
BROWN_BEAR,
5+
BLACK_BEAR,
6+
POLAR_BEAR,
7+
PANDA,
8+
SUN_BEAR,
9+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.querydsl.example.ksp
2+
3+
import jakarta.persistence.AttributeConverter
4+
import jakarta.persistence.Converter
5+
6+
@Converter
7+
class BearSpeciesConverter : AttributeConverter<BearSpecies, String> {
8+
9+
override fun convertToDatabaseColumn(attribute: BearSpecies?): String? {
10+
return attribute?.name?.lowercase()
11+
}
12+
13+
override fun convertToEntityAttribute(dbData: String?): BearSpecies? {
14+
return dbData?.let {
15+
try {
16+
BearSpecies.valueOf(it.uppercase())
17+
} catch (e: IllegalArgumentException) {
18+
null
19+
}
20+
}
21+
}
22+
}

querydsl-examples/querydsl-example-ksp-codegen/src/test/kotlin/Tests.kt

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import com.querydsl.example.ksp.Bear
2+
import com.querydsl.example.ksp.BearSpecies
23
import com.querydsl.example.ksp.Cat
34
import com.querydsl.example.ksp.CatType
45
import com.querydsl.example.ksp.Dog
@@ -181,7 +182,7 @@ class Tests {
181182
run {
182183
val em = emf.createEntityManager()
183184
em.transaction.begin()
184-
em.persist(Bear(424, "Winnie", "The forest"))
185+
em.persist(Bear(424, "Winnie", "The forest", null))
185186
em.transaction.commit()
186187
em.close()
187188
}
@@ -207,10 +208,40 @@ class Tests {
207208

208209
@Test
209210
fun `query projection exclude property from constructor`() {
210-
assertThat(Bear::class.declaredMemberProperties.count()).isEqualTo(3)
211+
assertThat(Bear::class.declaredMemberProperties.count()).isEqualTo(4)
211212
assertThat(QBearSimplifiedProjection::class.primaryConstructor!!.parameters.count()).isEqualTo(2)
212213
}
213214

215+
@Test
216+
fun `enum with convert annotation generates EnumPath`() {
217+
val emf = initialize()
218+
219+
run {
220+
val em = emf.createEntityManager()
221+
em.transaction.begin()
222+
em.persist(Bear(501, "Baloo", "Jungle", null))
223+
em.transaction.commit()
224+
em.close()
225+
}
226+
227+
run {
228+
val em = emf.createEntityManager()
229+
val queryFactory = JPAQueryFactory(em)
230+
val q = QBear.bear
231+
232+
val bears = queryFactory
233+
.select(q.species.coalesce(BearSpecies.BLACK_BEAR))
234+
.from(q)
235+
.orderBy(q.id.asc())
236+
.fetch()
237+
238+
assertThat(bears.size).isEqualTo(1)
239+
assertThat(bears[0]).isEqualTo(BearSpecies.BLACK_BEAR)
240+
241+
em.close()
242+
}
243+
}
244+
214245
@Test
215246
fun `create and query dog with jsonb tag`() {
216247
val emf = initialize()

querydsl-tooling/querydsl-ksp-codegen/src/main/kotlin/com/querydsl/ksp/codegen/TypeExtractor.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ class TypeExtractor(
145145
}
146146

147147
private fun userType(type: KSType): QPropertyType.Unknown? {
148+
if (type.isEnum()) {
149+
return null
150+
}
151+
148152
val userTypeAnnotations = listOf(
149153
ClassName("org.hibernate.annotations", "Type"),
150154
ClassName("org.hibernate.annotations", "JdbcTypeCode"),
@@ -204,3 +208,9 @@ private fun KSType.toClassNameSimple(): ClassName {
204208
else -> error("Could not compute ClassName for '$this'")
205209
}
206210
}
211+
212+
private fun KSType.isEnum(): Boolean {
213+
val referencedDeclaration = declaration
214+
215+
return referencedDeclaration is KSClassDeclaration && referencedDeclaration.classKind == ClassKind.ENUM_CLASS
216+
}

0 commit comments

Comments
 (0)