Skip to content

Conversation

@jbl428
Copy link
Contributor

@jbl428 jbl428 commented Nov 2, 2025

resolves #1452

Additional context

Root Cause:

The issue stems from a fundamental difference in how Java APT and KSP code generators handle type extraction:

  1. Java APT behavior: The APT implementation (ExtendedTypeFactory) does not consider the presence of @Convert annotations when determining path types. It solely analyzes the declared type's hierarchy (e.g., whether it implements Comparable or extends Number) to determine the appropriate path type.

  2. KSP behavior (before fix): The KSP TypeExtractor had a userType() method that checked for annotations including @Convert, @Type, and @JdbcTypeCode. When these annotations were present, the method would return Unknown type, which was then rendered as SimplePath<T>.

  3. Execution order issue: The fallbackType() method in TypeExtractor contains logic to check if a type implements Comparable or extends Number. Additionally, the referenceType() method handles enum types by generating EnumPath<T>. However, when @Convert annotation was present, the userType() method was called first in the type extraction chain (before fallbackType() and referenceType()), causing it to return Unknown type immediately. This prevented the type hierarchy analysis in fallbackType() and enum detection in referenceType() from ever being executed, resulting in:

    • SimplePath<T> being generated instead of the correct ComparablePath<T> or NumberPath<T> for Comparable/Number types
    • SimplePath<T> being generated instead of EnumPath<T> for enum types with @Convert annotation (as documented in PR #1411)

    The removal of the userType() method resolves both issues, allowing proper type detection based on type hierarchy and enum identification.

The Fix:

The fix removes the annotation-based type detection (userType() method) from TypeExtractor, allowing the type extraction logic to proceed directly to type hierarchy analysis. This ensures that:

  • Types implementing Comparable are correctly identified and generate ComparablePath<T> (e.g., YearMonth)
  • Types extending Number and implementing Comparable are correctly identified and generate NumberPath<T> (e.g., Money)
  • Enum types are correctly identified and generate EnumPath<T> (even when @Convert annotation is present), enabling enum-specific operations like coalesce()
  • The behavior matches Java APT implementation, which ignores annotation presence and focuses solely on type structure

Related Pull Requests:

  • PR #1263: Added fallbackType() method to handle unknown types by checking if they implement Comparable (generates ComparablePath) or fallback to SimplePath otherwise.
  • PR #1127: Modified userType() method to support @JdbcTypeCode annotation.
  • PR #1411: Fixed enum types with @Convert annotation generating SimplePath instead of EnumPath by removing the userType() method that was preventing proper enum detection in referenceType().

Remove annotation-based type detection that prevented proper type hierarchy
analysis. Types implementing Comparable or extending Number now correctly
generate ComparablePath and NumberPath respectively, matching Java APT behavior.

- Remove userType() method that checked for @convert, @type, @JdbcTypeCode
- Enhance fallbackType() to detect Comparable and Number via type hierarchy
- Add test cases for YearMonth (Comparable) and Money (Number+Comparable)
@codecov
Copy link

codecov bot commented Nov 2, 2025

Codecov Report

❌ Patch coverage is 0% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 0.00%. Comparing base (45ef040) to head (0642818).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...n/kotlin/com/querydsl/ksp/codegen/TypeExtractor.kt 0.00% 26 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master   #1453    +/-   ##
=======================================
  Coverage    0.00%   0.00%            
=======================================
  Files         813     838    +25     
  Lines       31432   31761   +329     
  Branches     3600    3610    +10     
=======================================
- Misses      31432   31761   +329     
Flag Coverage Δ
cubrid 0.00% <0.00%> (?)
db2 0.00% <0.00%> (?)
embedded 0.00% <0.00%> (?)
examples 0.00% <ø> (?)
firebird 0.00% <0.00%> (?)
mongodb 0.00% <0.00%> (?)
mysql 0.00% <0.00%> (?)
oracle 0.00% <0.00%> (?)
postgresql 0.00% <0.00%> (?)
test 0.00% <0.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@IceBlizz6
Copy link
Collaborator

Hey @jbl428

These changes looks interesting, just wanted to check one thing with you.
Did you use AI to generate the code and/or this change description?

@jbl428
Copy link
Contributor Author

jbl428 commented Nov 2, 2025

@IceBlizz6

I identified the root cause and how to fix it on my own,
but I did use AI assistance for writing the test code and implementation logic
(especially when working with KSP).

For the PR description, since English isn't my strong suit, I provided AI with
the PR links I referenced while investigating the issue and the reason why I
removed the userType method in my prompt, then asked it to generate the description
based on that context.

@velo velo requested a review from IceBlizz6 November 5, 2025 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

KSP generates SimplePath for Comparable/Number types with @Convert annotation

3 participants