From e84aae23f0174859f492897c8f191646c01f5025 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 31 Jul 2018 18:34:27 +0200 Subject: [PATCH] HHH-10603 Avoid doing distinct and comparisons on byte arrays They are stored as blobs starting with Oracle12cDialect and distinct and comparisons on blobs are not supported. Some tests were adapted, some are now skipped with Oracle12cDialect. --- .../MultiTypedBasicAttributesEntity.java | 20 ++--- .../jpa/test/criteria/ParameterTest.java | 18 ++-- .../test/criteria/basic/PredicateTest.java | 26 +++--- .../test/criteria/paths/ImplicitJoinTest.java | 15 ++-- .../jpa/test/criteria/paths/LineItem.java | 66 ++++++++++++++ .../jpa/test/criteria/paths/Order.java | 88 +++++++++++++++++++ .../org/hibernate/test/legacy/FooBarTest.java | 9 +- 7 files changed, 203 insertions(+), 39 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/paths/LineItem.java create mode 100644 hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/paths/Order.java diff --git a/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/MultiTypedBasicAttributesEntity.java b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/MultiTypedBasicAttributesEntity.java index 3267b8b0e2..a8ece15d23 100644 --- a/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/MultiTypedBasicAttributesEntity.java +++ b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/MultiTypedBasicAttributesEntity.java @@ -26,8 +26,8 @@ public class MultiTypedBasicAttributesEntity { @GeneratedValue( generator = "increment" ) @GenericGenerator( name = "increment", strategy = "increment" ) private Long id; - private byte[] someBytes; - private Byte[] someWrappedBytes; + private int[] someInts; + private Integer[] someWrappedIntegers; public Long getId() { return id; @@ -37,19 +37,19 @@ public class MultiTypedBasicAttributesEntity { this.id = id; } - public byte[] getSomeBytes() { - return someBytes; + public int[] getSomeInts() { + return someInts; } - public void setSomeBytes(byte[] someBytes) { - this.someBytes = someBytes; + public void setSomeInts(int[] someInts) { + this.someInts = someInts; } - public Byte[] getSomeWrappedBytes() { - return someWrappedBytes; + public Integer[] getSomeWrappedIntegers() { + return someWrappedIntegers; } - public void setSomeWrappedBytes(Byte[] someWrappedBytes) { - this.someWrappedBytes = someWrappedBytes; + public void setSomeWrappedIntegers(Integer[] someWrappedIntegers) { + this.someWrappedIntegers = someWrappedIntegers; } } diff --git a/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/ParameterTest.java b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/ParameterTest.java index 2314667918..7a201372b9 100644 --- a/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/ParameterTest.java +++ b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/ParameterTest.java @@ -40,12 +40,12 @@ public class ParameterTest extends BaseEntityManagerFunctionalTestCase { CriteriaQuery criteria = em.getCriteriaBuilder() .createQuery( MultiTypedBasicAttributesEntity.class ); Root rootEntity = criteria.from( MultiTypedBasicAttributesEntity.class ); - Path someBytesPath = rootEntity.get( MultiTypedBasicAttributesEntity_.someBytes ); - ParameterExpression param = em.getCriteriaBuilder().parameter( byte[].class, "theBytes" ); - criteria.where( em.getCriteriaBuilder().equal( someBytesPath, param ) ); + Path someIntsPath = rootEntity.get( MultiTypedBasicAttributesEntity_.someInts ); + ParameterExpression param = em.getCriteriaBuilder().parameter( int[].class, "theInts" ); + criteria.where( em.getCriteriaBuilder().equal( someIntsPath, param ) ); TypedQuery query = em.createQuery( criteria ); - query.setParameter( param, new byte[] { 1,1,1 } ); - assertThat( query.getParameterValue( param.getName() ), instanceOf( byte[].class) ); + query.setParameter( param, new int[] { 1,1,1 } ); + assertThat( query.getParameterValue( param.getName() ), instanceOf( int[].class) ); query.getResultList(); em.getTransaction().commit(); em.close(); @@ -58,12 +58,12 @@ public class ParameterTest extends BaseEntityManagerFunctionalTestCase { CriteriaQuery criteria = em.getCriteriaBuilder() .createQuery( MultiTypedBasicAttributesEntity.class ); Root rootEntity = criteria.from( MultiTypedBasicAttributesEntity.class ); - Path thePath = rootEntity.get( MultiTypedBasicAttributesEntity_.someWrappedBytes ); - ParameterExpression param = em.getCriteriaBuilder().parameter( Byte[].class, "theBytes" ); + Path thePath = rootEntity.get( MultiTypedBasicAttributesEntity_.someWrappedIntegers ); + ParameterExpression param = em.getCriteriaBuilder().parameter( Integer[].class, "theIntegers" ); criteria.where( em.getCriteriaBuilder().equal( thePath, param ) ); TypedQuery query = em.createQuery( criteria ); - query.setParameter( param, new Byte[] { Byte.valueOf((byte)1), Byte.valueOf((byte)1), Byte.valueOf((byte)1) } ); - assertThat( query.getParameterValue( param.getName() ), instanceOf( Byte[].class ) ); + query.setParameter( param, new Integer[] { Integer.valueOf(1), Integer.valueOf(1), Integer.valueOf(1) } ); + assertThat( query.getParameterValue( param.getName() ), instanceOf( Integer[].class ) ); query.getResultList(); em.getTransaction().commit(); em.close(); diff --git a/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/basic/PredicateTest.java b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/basic/PredicateTest.java index bd21d68e8b..c881176276 100644 --- a/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/basic/PredicateTest.java +++ b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/basic/PredicateTest.java @@ -6,7 +6,11 @@ */ package org.hibernate.jpa.test.criteria.basic; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import java.util.List; + import javax.persistence.EntityManager; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; @@ -14,20 +18,20 @@ import javax.persistence.criteria.Path; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; -import org.junit.Before; -import org.junit.Test; - +import org.hibernate.dialect.Oracle12cDialect; +import org.hibernate.dialect.Oracle8iDialect; +import org.hibernate.dialect.Oracle9Dialect; +import org.hibernate.dialect.OracleDialect; import org.hibernate.jpa.test.metamodel.AbstractMetamodelSpecificTest; import org.hibernate.jpa.test.metamodel.CreditCard; import org.hibernate.jpa.test.metamodel.CreditCard_; import org.hibernate.jpa.test.metamodel.Customer_; import org.hibernate.jpa.test.metamodel.Order; import org.hibernate.jpa.test.metamodel.Order_; - +import org.hibernate.testing.SkipForDialect; import org.hibernate.testing.TestForIssue; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import org.junit.Before; +import org.junit.Test; /** * Test the various predicates. @@ -211,7 +215,7 @@ public class PredicateTest extends AbstractMetamodelSpecificTest { em.getTransaction().begin(); CriteriaQuery orderCriteria = builder.createQuery( Order.class ); Root orderRoot = orderCriteria.from( Order.class ); - + orderCriteria.select( orderRoot ); Predicate p = builder.equal( orderRoot.get( "domen" ), new char[]{'r','u'} ); orderCriteria.where( p ); @@ -223,15 +227,17 @@ public class PredicateTest extends AbstractMetamodelSpecificTest { } /** - * Check predicate for field which has simple char array type (byte[]). + * Check predicate for field which has simple byte array type (byte[]). */ @Test + @SkipForDialect(value = Oracle12cDialect.class, jiraKey = "HHH-10603", + comment = "Oracle12cDialect uses blob to store byte arrays and it's not possible to compare blobs with simple equality operators.") public void testByteArray() { EntityManager em = getOrCreateEntityManager(); em.getTransaction().begin(); CriteriaQuery orderCriteria = builder.createQuery( Order.class ); Root orderRoot = orderCriteria.from( Order.class ); - + orderCriteria.select( orderRoot ); Predicate p = builder.equal( orderRoot.get( "number" ), new byte[]{'1','2'} ); orderCriteria.where( p ); diff --git a/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/paths/ImplicitJoinTest.java b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/paths/ImplicitJoinTest.java index 069a1ca3b8..4c9cae742c 100644 --- a/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/paths/ImplicitJoinTest.java +++ b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/paths/ImplicitJoinTest.java @@ -13,18 +13,19 @@ import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Join; import javax.persistence.criteria.Root; -import org.hibernate.jpa.test.metamodel.AbstractMetamodelSpecificTest; -import org.hibernate.jpa.test.metamodel.LineItem; -import org.hibernate.jpa.test.metamodel.LineItem_; -import org.hibernate.jpa.test.metamodel.Order; -import org.hibernate.jpa.test.metamodel.Order_; - +import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; import org.junit.Test; /** * @author Steve Ebersole */ -public class ImplicitJoinTest extends AbstractMetamodelSpecificTest { +public class ImplicitJoinTest extends BaseEntityManagerFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Order.class, LineItem.class }; + } + @Test public void testImplicitJoinFromExplicitCollectionJoin() { EntityManager em = getOrCreateEntityManager(); diff --git a/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/paths/LineItem.java b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/paths/LineItem.java new file mode 100644 index 0000000000..03583422f1 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/paths/LineItem.java @@ -0,0 +1,66 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.jpa.test.criteria.paths; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "LINEITEM_TABLE") +public class LineItem { + + private String id; + private int quantity; + private Order order; + + public LineItem() { + } + + public LineItem(String v1, int v2, Order v3) { + id = v1; + quantity = v2; + order = v3; + } + + public LineItem(String v1, int v2) { + id = v1; + quantity = v2; + } + + @Id + @Column(name = "ID") + public String getId() { + return id; + } + + public void setId(String v) { + id = v; + } + + @Column(name = "QUANTITY") + public int getQuantity() { + return quantity; + } + + public void setQuantity(int v) { + quantity = v; + } + + @ManyToOne + @JoinColumn(name = "FK1_FOR_ORDER_TABLE") + public Order getOrder() { + return order; + } + + public void setOrder(Order v) { + order = v; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/paths/Order.java b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/paths/Order.java new file mode 100644 index 0000000000..ff82ed9b80 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/jpa/test/criteria/paths/Order.java @@ -0,0 +1,88 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.jpa.test.criteria.paths; + +import java.util.Collection; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "ORDER_TABLE") +public class Order { + + private String id; + private double totalPrice; + private LineItem sampleLineItem; + private Collection lineItems = new java.util.ArrayList(); + + public Order() { + } + + public Order(String id, double totalPrice) { + this.id = id; + this.totalPrice = totalPrice; + } + + public Order(String id) { + this.id = id; + } + + // ==================================================================== + // getters and setters for State fields + + @Id + @Column(name = "ID") + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Column(name = "TOTALPRICE") + public double getTotalPrice() { + return totalPrice; + } + + public void setTotalPrice(double price) { + this.totalPrice = price; + } + + // ==================================================================== + // getters and setters for Association fields + + // 1x1 + + @OneToOne(cascade = CascadeType.REMOVE) + @JoinColumn(name = "FK0_FOR_LINEITEM_TABLE") + public LineItem getSampleLineItem() { + return sampleLineItem; + } + + public void setSampleLineItem(LineItem l) { + this.sampleLineItem = l; + } + + // 1xMANY + + @OneToMany(cascade = CascadeType.ALL, mappedBy = "order") + public Collection getLineItems() { + return lineItems; + } + + public void setLineItems(Collection c) { + this.lineItems = c; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/legacy/FooBarTest.java b/hibernate-core/src/test/java/org/hibernate/test/legacy/FooBarTest.java index 3c9ba5db95..a4e4107511 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/legacy/FooBarTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/legacy/FooBarTest.java @@ -53,6 +53,7 @@ import org.hibernate.dialect.HSQLDialect; import org.hibernate.dialect.InterbaseDialect; import org.hibernate.dialect.MckoiDialect; import org.hibernate.dialect.MySQLDialect; +import org.hibernate.dialect.Oracle12cDialect; import org.hibernate.dialect.Oracle8iDialect; import org.hibernate.dialect.PointbaseDialect; import org.hibernate.dialect.PostgreSQL81Dialect; @@ -1645,7 +1646,7 @@ public class FooBarTest extends LegacyTestCase { count++; } assertEquals(4, count); - iter = s.createQuery("select distinct foo from Foo foo") + iter = s.createQuery("select foo from Foo foo") .setMaxResults(2) .setFirstResult(2) .list() @@ -1656,7 +1657,7 @@ public class FooBarTest extends LegacyTestCase { count++; } assertTrue(count==2); - iter = s.createQuery("select distinct foo from Foo foo") + iter = s.createQuery("select foo from Foo foo") .setMaxResults(3) .list() .iterator(); @@ -2519,7 +2520,9 @@ public class FooBarTest extends LegacyTestCase { ).list(); assertTrue( "collection.elements find", list.size()==2 ); } - if (!(getDialect() instanceof SAPDBDialect) ) { // SAPDB doesn't like distinct with binary type + // SAPDB doesn't like distinct with binary type + // Oracle12cDialect stores binary types as blobs and do no support distinct on blobs + if ( !(getDialect() instanceof SAPDBDialect) && !(getDialect() instanceof Oracle12cDialect) ) { List list = s.createQuery( "select distinct foo from Baz baz join baz.fooArray foo" ).list(); assertTrue( "collection.elements find", list.size()==2 ); }