OpenLiberty / open-liberty

Open Liberty is a highly composable, fast to start, dynamic application server runtime environment
https://openliberty.io
Eclipse Public License 2.0
1.13k stars 578 forks source link

JPQL SELECT not allowing entity attribute without optional entity identification variable #28913

Open njr-11 opened 1 week ago

njr-11 commented 1 week ago

EcilpseLink is rejecting JPQL SELECT clauses where the entity attribute omits the optional entity identification variable. For example for, SELECT hexadecimal FROM AsciiCharacter WHERE hexadecimal IS NOT NULL AND thisCharacter = ?1, EclipseLink raises an error: "The identification variable 'hexadecimal' is not defined in the FROM clause". It shouldn't need to be defined the from clause because this JPQL query is intentionally written without the entity identification variable to be consistent with JDQL.

[6/26/24, 16:49:15:531 CDT] 00000053 id=1a3a180d io.openliberty.data.internal.persistence.RepositoryImpl      3 QueryInfo@3bcbaa55 Optional hex(char) SELECT hexadecimal FROM AsciiCharacter WHERE hexadecimal IS NOT NULL AND thisCharacter = ?1 [1 positional params]
[6/26/24, 16:49:15:531 CDT] 00000053 id=3bcbaa55 io.openliberty.data.internal.persistence.QueryInfo           3 hasDynamicSortCriteria? false
[6/26/24, 16:49:15:531 CDT] 00000053 id=45a6a820 enliberty.data.internal.persistence.service.DBStoreEMBuilder > createEntityManager Entry 
[6/26/24, 16:49:15:531 CDT] 00000053 id=1078ee11 om.ibm.wsspi.persistence.internal.PersistenceServiceUnitImpl > createEntityManager Entry 
[6/26/24, 16:49:15:531 CDT] 00000053 id=1078ee11 om.ibm.wsspi.persistence.internal.PersistenceServiceUnitImpl < createEntityManager Exit  
                                                                                                               org.eclipse.persistence.internal.jpa.EntityManagerImpl@7aa0a476
[6/26/24, 16:49:15:531 CDT] 00000053 id=45a6a820 enliberty.data.internal.persistence.service.DBStoreEMBuilder < createEntityManager Exit  
                                                                                                               org.eclipse.persistence.internal.jpa.EntityManagerImpl@7aa0a476
[6/26/24, 16:49:15:531 CDT] 00000053 id=1a3a180d io.openliberty.data.internal.persistence.RepositoryImpl      3 createQuery 
                                                                                                               SELECT hexadecimal FROM AsciiCharacter WHERE hexadecimal IS NOT NULL AND thisCharacter = ?1
                                                                                                               ee.jakarta.tck.data.framework.read.only.AsciiCharacter
[6/26/24, 16:49:15:531 CDT] 00000053 id=00000000 io.openliberty.data.internal.persistence.RepositoryImpl      3 java.lang.IllegalArgumentException replaced with jakarta.data.exceptions.MappingException
[6/26/24, 16:49:15:531 CDT] 00000053 id=1a3a180d io.openliberty.data.internal.persistence.RepositoryImpl      < invoke AsciiCharacters.hex Exit  
                                                                                                               jakarta.data.exceptions.MappingException: java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
Exception Description: Problem compiling [SELECT hexadecimal FROM AsciiCharacter WHERE hexadecimal IS NOT NULL AND thisCharacter = ?1]. 
[7, 18] The identification variable 'hexadecimal' is not defined in the FROM clause.
    at io.openliberty.data.internal.persistence.RepositoryImpl.failure(RepositoryImpl.java:302)
    at io.openliberty.data.internal.persistence.RepositoryImpl.invoke(RepositoryImpl.java:1256)
    at jdk.proxy11/jdk.proxy11.$Proxy93.hex(Unknown Source)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at org.jboss.weld.bean.proxy.AbstractBeanInstance.invoke(AbstractBeanInstance.java:38)
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:109)
    at ee.jakarta.tck.data.framework.read.only.AsciiCharacters$285707037$Proxy$_$$_WeldClientProxy.hex(Unknown Source)
    at ee.jakarta.tck.data.standalone.entity.EntityTest.testQueryWithNull(EntityTest.java:1386)
    at ee.jakarta.tck.data.standalone.entity.EntityTest$Proxy$_$$_WeldClientProxy.testQueryWithNull(Unknown Source)
    at ee.jakarta.tck.data.standalone.entity.EntityTestServlet.testQueryWithNull(EntityTestServlet.java:309)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at componenttest.app.FATServlet.doGet(FATServlet.java:74)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:633)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:723)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1266)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:754)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:451)
    at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1362)
    at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1078)
    at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:77)
    at com.ibm.ws.webcontainer40.servlet.CacheServletWrapper40.handleRequest(CacheServletWrapper40.java:87)
    at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:978)
    at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$2.run(DynamicVirtualHost.java:293)
    at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink$TaskWrapper.run(HttpDispatcherLink.java:1260)
    at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.wrapHandlerAndExecute(HttpDispatcherLink.java:476)
    at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.ready(HttpDispatcherLink.java:435)
    at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:569)
    at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleNewRequest(HttpInboundLink.java:503)
    at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.processRequest(HttpInboundLink.java:363)
    at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.ready(HttpInboundLink.java:330)
    at com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:169)
    at com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:77)
    at com.ibm.ws.tcpchannel.internal.WorkQueueManager.requestComplete(WorkQueueManager.java:516)
    at com.ibm.ws.tcpchannel.internal.WorkQueueManager.attemptIO(WorkQueueManager.java:586)
    at com.ibm.ws.tcpchannel.internal.WorkQueueManager.workerRun(WorkQueueManager.java:970)
    at com.ibm.ws.tcpchannel.internal.WorkQueueManager$Worker.run(WorkQueueManager.java:1059)
    at com.ibm.ws.threading.internal.ExecutorServiceImpl$RunnableWrapper.run(ExecutorServiceImpl.java:280)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
    at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
Exception Description: Problem compiling [SELECT hexadecimal FROM AsciiCharacter WHERE hexadecimal IS NOT NULL AND thisCharacter = ?1]. 
[7, 18] The identification variable 'hexadecimal' is not defined in the FROM clause.
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1848)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1869)
    at io.openliberty.data.internal.persistence.RepositoryImpl.invoke(RepositoryImpl.java:871)
    ... 40 more
Caused by: Exception [EclipseLink-0] (Eclipse Persistence Services - 5.0.0-B02.v202404111748): org.eclipse.persistence.exceptions.JPQLException
Exception Description: Problem compiling [SELECT hexadecimal FROM AsciiCharacter WHERE hexadecimal IS NOT NULL AND thisCharacter = ?1]. 
[7, 18] The identification variable 'hexadecimal' is not defined in the FROM clause.
    at org.eclipse.persistence.internal.jpa.jpql.HermesParser.buildException(HermesParser.java:169)
    at org.eclipse.persistence.internal.jpa.jpql.HermesParser.validate(HermesParser.java:358)
    at org.eclipse.persistence.internal.jpa.jpql.HermesParser.populateQueryImp(HermesParser.java:292)
    at org.eclipse.persistence.internal.jpa.jpql.HermesParser.buildQuery(HermesParser.java:174)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:144)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:120)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:107)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:91)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1846)
    ... 42 more
Riva-Tholoor-Philip commented 3 days ago

See EclipseLink Issue : 2182

tkburroughs commented 1 day ago

@njr-11 From the EclipseLink community (see https://github.com/eclipse-ee4j/eclipselink/issues/2182) :

given that If the domain has exactly one named entity abstract schema type and no joins, then the named entity does not require an explicit identification variable, and its identification variable defaults to the implicit identification variable, this. one should use either SELECT hexadecimal FROM AsciiCharacter hexadecimal WHERE ... or SELECT this FROM AsciiCharacter WHERE ...

So, agreement that use of an identifier on the "FROM" clause is optional, but when omitted, it defaults to "this", and therefore the identifier "hexadecimal" may not be used elsewhere, but instead it should be "this".

I confirmed that the wording above is from the JPA 3.2 final spec; though I'm not sure where exactly this is covered in the Data spec. Someone familiar with Jakarta Data needs to do one of the following:

njr-11 commented 17 hours ago

I added a reply in the EclipseLink issue to challenge their interpretation of the Jakarta Persistence 3.2 specification on this.