From ab1eab52976d4f7bd14e54a4690c31e04e5165a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Kraus?= Date: Wed, 25 Oct 2023 13:17:17 +0200 Subject: [PATCH] jakartaee/persistence#438 - add Expression.equalTo() and Expression.notEqualTo() added to SubQueryImpl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomáš Kraus --- .../test/query/model/TestQueryEqualTo.java | 245 ++++++++++++++++++ .../internal/jpa/EJBQueryImpl.java | 5 - .../jpa/StoredProcedureQueryImpl.java | 6 - .../internal/jpa/metamodel/MetamodelImpl.java | 2 - .../internal/jpa/querydef/SubQueryImpl.java | 36 ++- 5 files changed, 269 insertions(+), 25 deletions(-) create mode 100644 jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/query/model/TestQueryEqualTo.java diff --git a/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/query/model/TestQueryEqualTo.java b/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/query/model/TestQueryEqualTo.java new file mode 100644 index 00000000000..073452ccf6a --- /dev/null +++ b/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/query/model/TestQueryEqualTo.java @@ -0,0 +1,245 @@ +/* + * Copyright (c) 1998, 2023 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, + * or the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ + +// Contributors: +// 10/25/2023: Tomas Kraus +// - New Jakarta Persistence 3.2 Features +package org.eclipse.persistence.jpa.test.query.model; + +import java.util.List; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.TypedQuery; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.ParameterExpression; +import jakarta.persistence.criteria.Root; +import org.eclipse.persistence.jpa.test.framework.DDLGen; +import org.eclipse.persistence.jpa.test.framework.Emf; +import org.eclipse.persistence.jpa.test.framework.EmfRunner; +import org.eclipse.persistence.jpa.test.framework.Property; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +@RunWith(EmfRunner.class) +public class TestQueryEqualTo { + + @Emf(createTables = DDLGen.DROP_CREATE, classes = { EntityTbl01.class }, + properties = { @Property(name="eclipselink.logging.level", value="FINE")}) + private EntityManagerFactory emf; + + private static boolean POPULATED = false; + + @Test + public void testQueryEqualToExpression() { + if (!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + + try { + TypedQuery query = em.createQuery( + "SELECT t.KeyString FROM EntityTbl01 t " + + "WHERE t.KeyString = ?1", String.class); + query.setParameter(1, "EqualTo_1"); + List dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(1, dto01.size()); + + // equivalent CriteriaBuilder + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(String.class); + Root root = cquery.from(EntityTbl01.class); + ParameterExpression strParam1 = cb.parameter(String.class); + cquery.multiselect(root.get(EntityTbl01_.KeyString)); + cquery.where(root.get(EntityTbl01_.KeyString).equalTo(strParam1)); + query = em.createQuery(cquery); + query.setParameter(strParam1, "EqualTo_1"); + dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(1, dto01.size()); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + @Test + public void testQueryEqualToObject() { + if (!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + + try { + TypedQuery query = em.createQuery( + "SELECT t.KeyString FROM EntityTbl01 t " + + "WHERE t.KeyString = 'EqualTo_2'", String.class); + List dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(1, dto01.size()); + + // equivalent CriteriaBuilder + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(String.class); + Root root = cquery.from(EntityTbl01.class); + cquery.multiselect(root.get(EntityTbl01_.KeyString)); + cquery.where(root.get(EntityTbl01_.KeyString).equalTo("EqualTo_2")); + query = em.createQuery(cquery); + dto01 = query.getResultList(); + assertNotNull(dto01); + assertEquals(1, dto01.size()); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + @Test + public void testQueryNotEqualToExpression() { + if (!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + + try { + TypedQuery query = em.createQuery( + "SELECT t.KeyString FROM EntityTbl01 t " + + "WHERE t.KeyString <> ?1", String.class); + query.setParameter(1, "EqualTo_3"); + List dto01 = query.getResultList(); + assertNotNull(dto01); + assertTrue(dto01.size() > 1); + + // equivalent CriteriaBuilder + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(String.class); + Root root = cquery.from(EntityTbl01.class); + ParameterExpression strParam1 = cb.parameter(String.class); + cquery.multiselect(root.get(EntityTbl01_.KeyString)); + cquery.where(root.get(EntityTbl01_.KeyString).notEqualTo(strParam1)); + query = em.createQuery(cquery); + query.setParameter(strParam1, "EqualTo_3"); + dto01 = query.getResultList(); + assertNotNull(dto01); + assertTrue(dto01.size() > 1); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + @Test + public void testQueryNotEqualToObject() { + if (!POPULATED) + populate(); + + EntityManager em = emf.createEntityManager(); + + try { + TypedQuery query = em.createQuery( + "SELECT t.KeyString FROM EntityTbl01 t " + + "WHERE t.KeyString <> 'EqualTo_4'", String.class); + List dto01 = query.getResultList(); + assertNotNull(dto01); + assertTrue(dto01.size() > 1); + + // equivalent CriteriaBuilder + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(String.class); + Root root = cquery.from(EntityTbl01.class); + cquery.multiselect(root.get(EntityTbl01_.KeyString)); + cquery.where(root.get(EntityTbl01_.KeyString).notEqualTo("EqualTo_4")); + query = em.createQuery(cquery); + dto01 = query.getResultList(); + assertNotNull(dto01); + assertTrue(dto01.size() > 1); + } finally { + if (em.getTransaction().isActive()) { + em.getTransaction().rollback(); + } + if(em.isOpen()) { + em.close(); + } + } + } + + private void populate() { + EntityManager em = emf.createEntityManager(); + try { + em.getTransaction().begin(); + + EntityTbl01 tbl1 = new EntityTbl01(); + tbl1.setKeyString("EqualTo_1"); + tbl1.setItemString1("A"); + tbl1.setItemString2(null); + tbl1.setItemString3("C"); + tbl1.setItemString4("D"); + tbl1.setItemInteger1(45); + em.persist(tbl1); + + EntityTbl01 tbl2 = new EntityTbl01(); + tbl2.setKeyString("EqualTo_2"); + tbl2.setItemString1("A"); + tbl2.setItemString2("B"); + tbl2.setItemString3("C"); + tbl2.setItemString4(null); + tbl2.setItemInteger1(83); + em.persist(tbl2); + + EntityTbl01 tbl3 = new EntityTbl01(); + tbl3.setKeyString("EqualTo_3"); + tbl3.setItemString1(null); + tbl3.setItemString2("B"); + tbl3.setItemString3("C"); + tbl3.setItemString4("D"); + tbl3.setItemInteger1(17); + em.persist(tbl3); + + EntityTbl01 tbl4 = new EntityTbl01(); + tbl4.setKeyString("EqualTo_4"); + tbl4.setItemString1("A"); + tbl4.setItemString2("B"); + tbl4.setItemString3("C"); + tbl4.setItemString4(null); + tbl4.setItemInteger1(29); + em.persist(tbl4); + + em.getTransaction().commit(); + + POPULATED = true; + } finally { + if(em.isOpen()) { + em.close(); + } + } + } + + +} diff --git a/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/EJBQueryImpl.java b/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/EJBQueryImpl.java index 8953db3049d..12b98c527c4 100644 --- a/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/EJBQueryImpl.java +++ b/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/EJBQueryImpl.java @@ -41,10 +41,7 @@ import jakarta.persistence.Parameter; import jakarta.persistence.PersistenceException; import jakarta.persistence.TemporalType; -import jakarta.persistence.Timeout; import jakarta.persistence.TypedQuery; - -import org.eclipse.persistence.config.QueryHints; import org.eclipse.persistence.exceptions.QueryException; import org.eclipse.persistence.expressions.Expression; import org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform; @@ -56,8 +53,6 @@ import org.eclipse.persistence.internal.queries.JPQLCallQueryMechanism; import org.eclipse.persistence.internal.sessions.AbstractSession; import org.eclipse.persistence.jpa.JpaQuery; -import org.eclipse.persistence.logging.AbstractSessionLog; -import org.eclipse.persistence.logging.SessionLog; import org.eclipse.persistence.queries.Cursor; import org.eclipse.persistence.queries.DataReadQuery; import org.eclipse.persistence.queries.DatabaseQuery; diff --git a/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/StoredProcedureQueryImpl.java b/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/StoredProcedureQueryImpl.java index 2d7a23caec6..9637c911674 100644 --- a/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/StoredProcedureQueryImpl.java +++ b/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/StoredProcedureQueryImpl.java @@ -880,39 +880,33 @@ public StoredProcedureQueryImpl setFlushMode(FlushModeType flushMode) { return (StoredProcedureQueryImpl) super.setFlushMode(flushMode); } - // TODO-API-3.2 @Override public CacheRetrieveMode getCacheRetrieveMode() { return FindOptionUtils.getCacheRetrieveMode(getDatabaseQuery().getProperties()); } - // TODO-API-3.2 @Override public StoredProcedureQueryImpl setCacheRetrieveMode(CacheRetrieveMode cacheRetrieveMode) { FindOptionUtils.setCacheRetrieveMode(getDatabaseQuery().getProperties(), cacheRetrieveMode); return this; } - // TODO-API-3.2 @Override public CacheStoreMode getCacheStoreMode() { return FindOptionUtils.getCacheStoreMode(getDatabaseQuery().getProperties()); } - // TODO-API-3.2 @Override public StoredProcedureQueryImpl setCacheStoreMode(CacheStoreMode cacheStoreMode) { FindOptionUtils.setCacheStoreMode(getDatabaseQuery().getProperties(), cacheStoreMode); return this; } - // TODO-API-3.2 @Override public Integer getTimeout() { return FindOptionUtils.getTimeout(getDatabaseQuery().getProperties()); } - // TODO-API-3.2 @Override public StoredProcedureQueryImpl setTimeout(Integer timeout) { FindOptionUtils.setTimeout(getDatabaseQuery().getProperties(), timeout); diff --git a/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/metamodel/MetamodelImpl.java b/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/metamodel/MetamodelImpl.java index e63e1900974..2eef995a3f8 100644 --- a/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/metamodel/MetamodelImpl.java +++ b/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/metamodel/MetamodelImpl.java @@ -205,8 +205,6 @@ private void entityEmbeddableManagedTypeNotFound(Map typeMap, Object aType, Stri } } - - // TODO-API-3.2 @Override public EntityType entity(String entityName) { EntityTypeImpl aType = this.entities.get(entityName); diff --git a/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/querydef/SubQueryImpl.java b/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/querydef/SubQueryImpl.java index cfd3948f3a4..b56910b883f 100644 --- a/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/querydef/SubQueryImpl.java +++ b/jpa/org.eclipse.persistence.jpa/src/main/java/org/eclipse/persistence/internal/jpa/querydef/SubQueryImpl.java @@ -494,28 +494,40 @@ public Predicate isNotNull() { return new CompoundExpressionImpl(this.metamodel, this.currentNode.notNull(), list, "not null"); } - // TODO-API-3.2 @Override - public Predicate equalTo(Expression expression) { - throw new UnsupportedOperationException("Jakarta Persistence 3.2 API was not implemented yet"); + public Predicate equalTo(Expression value) { + return new CompoundExpressionImpl( + this.metamodel, + this.currentNode.equal(value), + List.of(this, value), + "equals"); } - // TODO-API-3.2 @Override - public Predicate equalTo(Object o) { - throw new UnsupportedOperationException("Jakarta Persistence 3.2 API was not implemented yet"); + public Predicate equalTo(Object value) { + return new CompoundExpressionImpl( + this.metamodel, + this.currentNode.equal(value), + List.of(this, ExpressionImpl.createLiteral(value, metamodel)), + "equals"); } - // TODO-API-3.2 @Override - public Predicate notEqualTo(Expression expression) { - throw new UnsupportedOperationException("Jakarta Persistence 3.2 API was not implemented yet"); + public Predicate notEqualTo(Expression value) { + return new CompoundExpressionImpl( + this.metamodel, + this.currentNode.equal(value), + List.of(this, value), + "not equal"); } - // TODO-API-3.2 @Override - public Predicate notEqualTo(Object o) { - throw new UnsupportedOperationException("Jakarta Persistence 3.2 API was not implemented yet"); + public Predicate notEqualTo(Object value) { + return new CompoundExpressionImpl( + this.metamodel, + this.currentNode.equal(value), + List.of(this, ExpressionImpl.createLiteral(value, metamodel)), + "not equal"); } @Override