eclipselink
eclipselink copied to clipboard
ClassCastException for Complex Query with Multiple Bi-Directional Associations
Given the following setup, a ClassCastException ends up being thrown when running the following (admittedly inefficient) named query.
@NamedQuery(
name = "getPlannedWorksDuringTimePeriod_fail",
query = "SELECT w from Work w",
hints = {
@QueryHint(
name = QueryHints.LEFT_FETCH,
value = "i.impact"
),
@QueryHint(
name = QueryHints.LEFT_FETCH,
value = "i.ticket"
),
@QueryHint(
name = QueryHints.LEFT_FETCH,
value = "i.impact.items"
),
@QueryHint(
name = QueryHints.LEFT_FETCH,
value = "i.impact.items.service"
)
}
)
java.lang.ClassCastException: class bug.eclipselink.jpa.Ticket cannot be cast to class bug.eclipselink.jpa.Service (bug.eclipselink.jpa.Ticket and bug.eclipselink.jpa.Service are in unnamed module of loader org.glassfish.web.loader.WebappClassLoader @727cfd08)
I looked into it a bit, and it seems to be coming from that once it has trimmed the row and started trying to do a get with the primary key, said key still maps to two fields (and it gets the wrong one).
Primary Key: AUDITABLE.ID
This is where it's starting to get a bit too deep into the codebase for me to just eyeball where it's going wrong. I'm not sure if the flaw lies within the generated JoinAttributeManager
which determines the trimming, in the logic of the ObjectBuilder#extractPrimaryKeyFromRow
or ForeignReferenceMapping#trimRowForJoin
methods, or if it went wrong from the get-go by generating incorrect SQL for the named query (the SQL generated is valid)
Reproduction app attached, reproduced on Payara 5.2021.7 (Eclipselink 2.7.7) with MySQL jpa-bug-200625.zip
- Start Payara
- Install MySQL Connector J for desired MySQL version
- Create JDBC Connection Pool for MySQL database
- Create JDBC Resource mapped to MySQL Connection Pool with JNDI lookup of
jdbc/local-mysql
- Deploy application
- Hit JAX-RS endpoint to run named query: http://localhost:8080/jpa-bug-200625/posts/fail