diff --git a/foundation/org.eclipse.persistence.core.test.framework/src/main/java/org/eclipse/persistence/testing/framework/TogglingFastTableCreator.java b/foundation/org.eclipse.persistence.core.test.framework/src/main/java/org/eclipse/persistence/testing/framework/TogglingFastTableCreator.java index 3902983d29d..e9b1f5f594f 100644 --- a/foundation/org.eclipse.persistence.core.test.framework/src/main/java/org/eclipse/persistence/testing/framework/TogglingFastTableCreator.java +++ b/foundation/org.eclipse.persistence.core.test.framework/src/main/java/org/eclipse/persistence/testing/framework/TogglingFastTableCreator.java @@ -354,6 +354,40 @@ protected static FieldDefinition createDateColumn( return createDateColumn(name, 23, true); } + /** + * Helper method to create {@link FieldDefinition} instance + * for {@link java.time.LocalTime} column with given name and size and without + * any additional constraints. + * @param name Column name. + * @param size Column date size. + * @param allowNull Allow {@code null} values for column. + * @return Initialized {@link FieldDefinition} instance. + */ + protected static FieldDefinition createTimeColumn( + final String name, final int size, final boolean allowNull) { + final FieldDefinition field = new FieldDefinition(); + field.setName(name); + field.setTypeName("TIME"); + field.setSize(size); + field.setShouldAllowNull(allowNull); + field.setIsPrimaryKey(false); + field.setUnique(false); + field.setIsIdentity(false); + return field; + } + + /** + * Helper method to create {@link FieldDefinition} instance + * for {@link java.time.LocalTime} column with given name size of {@code 23}, + * with {@code null} value allowed and without any additional constraints. + * @param name Column name. + * @return Initialized {@link FieldDefinition} instance. + */ + protected static FieldDefinition createTimeColumn( + final String name) { + return createDateColumn(name, 23, true); + } + protected void adjustForeignKeyFieldTypes(DatabaseSession session) { for (TableDefinition sourceTableDefinition : getTableDefinitions() ) { for (FieldDefinition sourceFieldDefinition : sourceTableDefinition.getFields()) { // see TableDefinition, l.789 diff --git a/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/main/java/org/eclipse/persistence/testing/models/jpa/persistence32/Persistence32TableCreator.java b/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/main/java/org/eclipse/persistence/testing/models/jpa/persistence32/Persistence32TableCreator.java index 66e2bf158eb..3fd7fb09fa8 100644 --- a/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/main/java/org/eclipse/persistence/testing/models/jpa/persistence32/Persistence32TableCreator.java +++ b/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/main/java/org/eclipse/persistence/testing/models/jpa/persistence32/Persistence32TableCreator.java @@ -55,8 +55,8 @@ public static TableDefinition buildSyntaxEntityTable() { table.addField(createNumericPk("ID")); table.addField(createStringColumn("STR_VAL_1", 128, true)); table.addField(createStringColumn("STR_VAL_2", 128, true)); - table.addField(createNumericColumn("INT_VAL_1", 15, true)); - table.addField(createNumericColumn("INT_VAL_2", 15, true)); + table.addField(createNumericColumn("INT_VAL", 15, true)); + table.addField(createTimeColumn("TIME_VAL", 15, true)); return table; } diff --git a/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/main/java/org/eclipse/persistence/testing/models/jpa/persistence32/SyntaxEntity.java b/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/main/java/org/eclipse/persistence/testing/models/jpa/persistence32/SyntaxEntity.java index a2bfb3e33e4..342d64adb74 100644 --- a/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/main/java/org/eclipse/persistence/testing/models/jpa/persistence32/SyntaxEntity.java +++ b/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/main/java/org/eclipse/persistence/testing/models/jpa/persistence32/SyntaxEntity.java @@ -1,5 +1,6 @@ package org.eclipse.persistence.testing.models.jpa.persistence32; +import java.time.LocalTime; import java.util.Collection; import jakarta.persistence.CollectionTable; @@ -23,14 +24,16 @@ public class SyntaxEntity { @Column(name = "STR_VAL_2") private String strVal2; - @Column(name = "INT_VAL_1") - private Integer intVal1; - @Column(name = "INT_VAL_2") - private Integer intVal2; + @Column(name = "INT_VAL") + private Integer intVal; + + @Column(name = "TIME_VAL") + private LocalTime timeVal; + @ElementCollection @CollectionTable(name = "COLTABLE1", joinColumns = @JoinColumn(name = "ent_id")) - private Collection colVal1; + private Collection colVal; public SyntaxEntity() { } @@ -39,9 +42,13 @@ public SyntaxEntity(Long id) { this.id = id; } - public SyntaxEntity(Long id, String strVal1, String strVal2, Integer intVal1, Integer intVal2) { + public SyntaxEntity(Long id, String strVal1, String strVal2, Integer intVal, LocalTime timeVal, Collection colVal) { this.id = id; this.strVal1 = strVal1; + this.strVal2 = strVal2; + this.intVal = intVal; + this.timeVal = timeVal; + this.colVal = colVal; } public long getId() { @@ -68,20 +75,20 @@ public void setStrVal2(String strVal2) { this.strVal2 = strVal2; } - public Integer getIntVal1() { - return intVal1; + public Integer getIntVal() { + return intVal; } - public void setIntVal1(Integer intVal1) { - this.intVal1 = intVal1; + public void setIntVal(Integer intVal) { + this.intVal = intVal; } - public Integer getIntVal2() { - return intVal2; + public LocalTime getTimeVal() { + return timeVal; } - public void setIntVal2(Integer intVal2) { - this.intVal2 = intVal2; + public void setTimeVal(LocalTime timeVal) { + this.timeVal = timeVal; } } diff --git a/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/test/java/org/eclipse/persistence/testing/tests/jpa/persistence32/CriteriaBuilderTests.java b/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/test/java/org/eclipse/persistence/testing/tests/jpa/persistence32/CriteriaBuilderTests.java index a41bae88b97..9fa984a3cbb 100644 --- a/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/test/java/org/eclipse/persistence/testing/tests/jpa/persistence32/CriteriaBuilderTests.java +++ b/jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/test/java/org/eclipse/persistence/testing/tests/jpa/persistence32/CriteriaBuilderTests.java @@ -1,5 +1,6 @@ package org.eclipse.persistence.testing.tests.jpa.persistence32; +import java.time.LocalTime; import java.util.List; import jakarta.persistence.EntityManager; @@ -7,6 +8,7 @@ import jakarta.persistence.TypedQuery; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.LocalTimeField; import jakarta.persistence.criteria.ParameterExpression; import jakarta.persistence.criteria.Root; import junit.framework.Test; @@ -23,9 +25,10 @@ public class CriteriaBuilderTests extends JUnitTestCase { // SyntaxEntity instances, array index is equal to ID private static final SyntaxEntity[] ENTITIES = new SyntaxEntity[] { null, // Skip array index 0 - new SyntaxEntity(1L, "Left", null, null, null), - new SyntaxEntity(2L, "right", null, null, null), - new SyntaxEntity(3L, "LeftToken", "TokenRight", null, null) + new SyntaxEntity(1L, "Left", null, null, null, null), + new SyntaxEntity(2L, "right", null, null, null, null), + new SyntaxEntity(3L, "LeftToken", "TokenRight", null, null, null), + new SyntaxEntity(4L, null, null, null, LocalTime.of(10, 11, 12), null) }; private JpaEntityManagerFactory emf = null; @@ -39,6 +42,12 @@ public static Test suite() { suite.addTest(new CriteriaBuilderTests("testRightIntLen")); suite.addTest(new CriteriaBuilderTests("testRightExprLen")); suite.addTest(new CriteriaBuilderTests("testReplaceExprExpr")); + suite.addTest(new CriteriaBuilderTests("testReplaceExprStr")); + suite.addTest(new CriteriaBuilderTests("testReplaceStrExpr")); + suite.addTest(new CriteriaBuilderTests("testReplaceStrStr")); + suite.addTest(new CriteriaBuilderTests("testExtractHourFromTime")); + suite.addTest(new CriteriaBuilderTests("testExtractMinuteFromTime")); + suite.addTest(new CriteriaBuilderTests("testExtractSecondFromTime")); return suite; } @@ -193,7 +202,160 @@ public void testReplaceExprExpr() { query.setParameter(strParam1, "UnknownToken"); List result = query.getResultList(); Assert.assertEquals(1, result.size()); - Assert.assertEquals(2L, result.get(0).getId()); + Assert.assertEquals(3L, result.get(0).getId()); + et.commit(); + } catch (Exception e) { + et.rollback(); + throw e; + } + } + } + + public void testReplaceExprStr() { + // Skip for Derby + if (emf.getServerSession().getPlatform().isDerby()) { + return; + } + try (EntityManager em = emf.createEntityManager()) { + EntityTransaction et = em.getTransaction(); + try { + et.begin(); + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(SyntaxEntity.class); + Root root = cquery.from(SyntaxEntity.class); + ParameterExpression strParam2 = cb.parameter(String.class, "strParam2"); + cquery.where(cb.equal(root.get("strVal2"), cb.replace(strParam2, cb.literal("Unknown"), "Right"))); + TypedQuery query = em.createQuery(cquery); + query.setParameter(strParam2, "TokenUnknown"); + List result = query.getResultList(); + Assert.assertEquals(1, result.size()); + Assert.assertEquals(3L, result.get(0).getId()); + et.commit(); + } catch (Exception e) { + et.rollback(); + throw e; + } + } + } + + public void testReplaceStrExpr() { + // Skip for Derby + if (emf.getServerSession().getPlatform().isDerby()) { + return; + } + try (EntityManager em = emf.createEntityManager()) { + EntityTransaction et = em.getTransaction(); + try { + et.begin(); + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(SyntaxEntity.class); + Root root = cquery.from(SyntaxEntity.class); + ParameterExpression strParam1 = cb.parameter(String.class, "strParam1"); + cquery.where(cb.equal(root.get("strVal1"), cb.replace(strParam1, "Unknown", cb.literal("Left")))); + TypedQuery query = em.createQuery(cquery); + query.setParameter(strParam1, "UnknownToken"); + List result = query.getResultList(); + Assert.assertEquals(1, result.size()); + Assert.assertEquals(3L, result.get(0).getId()); + et.commit(); + } catch (Exception e) { + et.rollback(); + throw e; + } + } + } + + public void testReplaceStrStr() { + // Skip for Derby + if (emf.getServerSession().getPlatform().isDerby()) { + return; + } + try (EntityManager em = emf.createEntityManager()) { + EntityTransaction et = em.getTransaction(); + try { + et.begin(); + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(SyntaxEntity.class); + Root root = cquery.from(SyntaxEntity.class); + ParameterExpression strParam2 = cb.parameter(String.class, "strParam2"); + cquery.where(cb.equal(root.get("strVal2"), cb.replace(strParam2, "Unknown", "Right"))); + TypedQuery query = em.createQuery(cquery); + query.setParameter(strParam2, "TokenUnknown"); + List result = query.getResultList(); + Assert.assertEquals(1, result.size()); + Assert.assertEquals(3L, result.get(0).getId()); + et.commit(); + } catch (Exception e) { + et.rollback(); + throw e; + } + } + } + + public void testExtractHourFromTime() { + try (EntityManager em = emf.createEntityManager()) { + EntityTransaction et = em.getTransaction(); + try { + et.begin(); + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(SyntaxEntity.class); + Root root = cquery.from(SyntaxEntity.class); + cquery.where(cb.equal( + cb.parameter(LocalTime.class, "timeParam"), + cb.extract(LocalTimeField.HOUR, root.get("timeVal")))); + TypedQuery query = em.createQuery(cquery); + query.setParameter("timeParam", 10); + List result = query.getResultList(); + Assert.assertEquals(1, result.size()); + Assert.assertEquals(4L, result.get(0).getId()); + et.commit(); + } catch (Exception e) { + et.rollback(); + throw e; + } + } + } + + public void testExtractMinuteFromTime() { + try (EntityManager em = emf.createEntityManager()) { + EntityTransaction et = em.getTransaction(); + try { + et.begin(); + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(SyntaxEntity.class); + Root root = cquery.from(SyntaxEntity.class); + cquery.where(cb.equal( + cb.parameter(LocalTime.class, "timeParam"), + cb.extract(LocalTimeField.MINUTE, root.get("timeVal")))); + TypedQuery query = em.createQuery(cquery); + query.setParameter("timeParam", 11); + List result = query.getResultList(); + Assert.assertEquals(1, result.size()); + Assert.assertEquals(4L, result.get(0).getId()); + et.commit(); + } catch (Exception e) { + et.rollback(); + throw e; + } + } + } + + public void testExtractSecondFromTime() { + try (EntityManager em = emf.createEntityManager()) { + EntityTransaction et = em.getTransaction(); + try { + et.begin(); + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cquery = cb.createQuery(SyntaxEntity.class); + Root root = cquery.from(SyntaxEntity.class); + cquery.where(cb.equal( + cb.parameter(LocalTime.class, "timeParam"), + cb.extract(LocalTimeField.SECOND, root.get("timeVal")))); + TypedQuery query = em.createQuery(cquery); + query.setParameter("timeParam", 12); + List result = query.getResultList(); + Assert.assertEquals(1, result.size()); + Assert.assertEquals(4L, result.get(0).getId()); et.commit(); } catch (Exception e) { et.rollback();