eclipselink icon indicating copy to clipboard operation
eclipselink copied to clipboard

ClassCastException for Complex Query with Multiple Bi-Directional Associations

Open Pandrex247 opened this issue 3 years ago • 0 comments

Given the following setup, a ClassCastException ends up being thrown when running the following (admittedly inefficient) named query.

image

@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 databaserows

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

Pandrex247 avatar Sep 22 '21 11:09 Pandrex247