From ca1c2efaf9552412ee296070a76d9bb4fe9f8013 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 31 Aug 2015 09:25:53 -0500 Subject: [PATCH] HHH-9954 - Equality checking should consider arrays --- .../util/collections/ArrayHelper.java | 9 ++ .../internal/util/compare/EqualsHelper.java | 86 ++++++++++++++++++- .../test/annotations/lob/ImageTest.java | 11 +-- .../test/annotations/lob/TextTest.java | 11 +-- .../hibernate/test/lob/BlobLocatorTest.java | 4 +- .../org/hibernate/test/lob/LobMergeTest.java | 7 +- .../hibernate/test/lob/LongByteArrayTest.java | 11 +-- .../sql/hand/custom/CustomSQLTestSupport.java | 12 +-- .../sql/hand/query/NativeSQLQueriesTest.java | 4 +- ...TestLazyPropertyOnPreUpdateExecutable.java | 6 +- 10 files changed, 126 insertions(+), 35 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/collections/ArrayHelper.java b/hibernate-core/src/main/java/org/hibernate/internal/util/collections/ArrayHelper.java index 2e8d9be2b5..bd6abf56fb 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/util/collections/ArrayHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/util/collections/ArrayHelper.java @@ -329,7 +329,10 @@ public final class ArrayHelper { /** * Compare 2 arrays only at the first level + * + * @deprecated Use {@link java.util.Arrays#equals(Object[], Object[])} instead */ + @Deprecated public static boolean isEquals(Object[] o1, Object[] o2) { if ( o1 == o2 ) { return true; @@ -351,7 +354,10 @@ public final class ArrayHelper { /** * Compare 2 arrays only at the first level + * + * @deprecated Use {@link java.util.Arrays#equals(char[], char[])} instead */ + @Deprecated public static boolean isEquals(char[] o1, char[] o2) { if ( o1 == o2 ) { return true; @@ -373,7 +379,10 @@ public final class ArrayHelper { /** * Compare 2 arrays only at the first level + * + * @deprecated Use {@link java.util.Arrays#equals(byte[], byte[])} instead */ + @Deprecated public static boolean isEquals(byte[] b1, byte[] b2) { if ( b1 == b2 ) { return true; diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/compare/EqualsHelper.java b/hibernate-core/src/main/java/org/hibernate/internal/util/compare/EqualsHelper.java index 95ac7f098a..6a83a58b74 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/util/compare/EqualsHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/util/compare/EqualsHelper.java @@ -6,16 +6,96 @@ */ package org.hibernate.internal.util.compare; +import java.util.Arrays; /** + * Helper for equality determination + * * @author Gavin King + * @author Steve Ebersole */ public final class EqualsHelper { + @SuppressWarnings("SimplifiableIfStatement") public static boolean equals(final Object x, final Object y) { - return x == y || ( x != null && y != null && x.equals( y ) ); + if ( x == y ) { + return true; + } + + if ( x == null || y == null ) { + // One is null, but the other is not (otherwise the `x == y` check would have passed). + // null can never equal a non-null + return false; + } + + return x.equals( y ); + } + + /** + * Like the legacy {@link #equals} method, but handles array-specific checks + * + * @param x One value to check + * @param y The other value + * + * @return {@code true} if the 2 values are equal; {@code false} otherwise. + */ + public static boolean areEqual(final Object x, final Object y) { + if ( x == y ) { + return true; + } + + if ( x == null || y == null ) { + // One is null, but the other is not (otherwise the `x == y` check would have passed). + // null can never equal a non-null + return false; + } + + if ( x.equals( y ) ) { + return true; + } + + // Check for possibility of arrays + final Class xClass = x.getClass(); + final Class yClass = y.getClass(); + + if ( xClass.isArray() && yClass.isArray() ) { + if ( xClass.equals( yClass ) ) { + if ( x instanceof boolean[] ) { + return Arrays.equals( (boolean[]) x, (boolean[]) y ); + } + else if ( x instanceof byte[] ) { + return Arrays.equals( (byte[]) x, (byte[]) y ); + } + else if ( x instanceof char[] ) { + return Arrays.equals( (char[]) x, (char[]) y ); + } + else if ( x instanceof short[] ) { + return Arrays.equals( (short[]) x, (short[]) y ); + } + else if ( x instanceof int[] ) { + return Arrays.equals( (int[]) x, (int[]) y ); + } + else if ( x instanceof long[] ) { + return Arrays.equals( (long[]) x, (long[]) y ); + } + else if ( x instanceof double[] ) { + return Arrays.equals( (double[]) x, (double[]) y ); + } + else if ( x instanceof float[] ) { + return Arrays.equals( (float[]) x, (float[]) y ); + } + } + return Arrays.equals( (Object[]) x, (Object[]) y ); + } + + return false; + } + + /** + * Private ctor - disallow instantiation + */ + private EqualsHelper() { + // disallow instantiation } - - private EqualsHelper() {} } diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/ImageTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/ImageTest.java index 29f06e3f9d..59b52b04ee 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/ImageTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/ImageTest.java @@ -6,18 +6,19 @@ */ package org.hibernate.test.annotations.lob; -import junit.framework.AssertionFailedError; -import org.junit.Assert; -import org.junit.Test; +import java.util.Arrays; import org.hibernate.Session; import org.hibernate.dialect.SQLServerDialect; import org.hibernate.dialect.Sybase11Dialect; import org.hibernate.dialect.SybaseASE15Dialect; import org.hibernate.dialect.SybaseDialect; -import org.hibernate.internal.util.collections.ArrayHelper; + import org.hibernate.testing.RequiresDialect; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Assert; +import org.junit.Test; +import junit.framework.AssertionFailedError; /** * Tests eager materialization and mutation of data mapped by @@ -130,7 +131,7 @@ public class ImageTest extends BaseCoreFunctionalTestCase { } public static void assertEquals(byte[] val1, byte[] val2) { - if (!ArrayHelper.isEquals( val1, val2 )) { + if ( !Arrays.equals( val1, val2 ) ) { throw new AssertionFailedError("byte arrays did not match"); } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/TextTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/TextTest.java index 45aea648ea..e3b0cbfa7a 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/TextTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/lob/TextTest.java @@ -6,18 +6,19 @@ */ package org.hibernate.test.annotations.lob; -import junit.framework.AssertionFailedError; -import org.junit.Assert; -import org.junit.Test; +import java.util.Arrays; import org.hibernate.Session; import org.hibernate.dialect.SQLServerDialect; import org.hibernate.dialect.Sybase11Dialect; import org.hibernate.dialect.SybaseASE15Dialect; import org.hibernate.dialect.SybaseDialect; -import org.hibernate.internal.util.collections.ArrayHelper; + import org.hibernate.testing.RequiresDialect; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Assert; +import org.junit.Test; +import junit.framework.AssertionFailedError; import static org.junit.Assert.assertNull; @@ -110,7 +111,7 @@ public class TextTest extends BaseCoreFunctionalTestCase { } public static void assertEquals(char[] val1, char[] val2) { - if (!ArrayHelper.isEquals( val1, val2 )) { + if ( !Arrays.equals( val1, val2 ) ) { throw new AssertionFailedError("byte arrays did not match"); } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/lob/BlobLocatorTest.java b/hibernate-core/src/test/java/org/hibernate/test/lob/BlobLocatorTest.java index b666efe338..7242d1ead7 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/lob/BlobLocatorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/lob/BlobLocatorTest.java @@ -7,12 +7,12 @@ package org.hibernate.test.lob; import java.sql.Blob; +import java.util.Arrays; import org.hibernate.Hibernate; import org.hibernate.LockOptions; import org.hibernate.Session; import org.hibernate.dialect.TeradataDialect; -import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.testing.DialectChecks; import org.hibernate.testing.RequiresDialectFeature; @@ -180,7 +180,7 @@ public class BlobLocatorTest extends BaseCoreFunctionalTestCase { } public static void assertEquals(byte[] val1, byte[] val2) { - if ( !ArrayHelper.isEquals( val1, val2 ) ) { + if ( !Arrays.equals( val1, val2 ) ) { throw new AssertionFailedError( "byte arrays did not match" ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/lob/LobMergeTest.java b/hibernate-core/src/test/java/org/hibernate/test/lob/LobMergeTest.java index 140ce5c67f..ebb6de20b8 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/lob/LobMergeTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/lob/LobMergeTest.java @@ -6,14 +6,15 @@ */ package org.hibernate.test.lob; -import org.junit.Test; +import java.util.Arrays; import org.hibernate.Session; -import org.hibernate.internal.util.collections.ArrayHelper; + import org.hibernate.testing.DialectChecks; import org.hibernate.testing.RequiresDialectFeature; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -58,7 +59,7 @@ public class LobMergeTest extends BaseCoreFunctionalTestCase { assertEquals( "blob sizes did not match after merge", LOB_SIZE, entity.getBlobLocator().length() ); assertTrue( "blob contents did not match after merge", - ArrayHelper.isEquals( updated, BlobLocatorTest.extractData( entity.getBlobLocator() ) ) + Arrays.equals( updated, BlobLocatorTest.extractData( entity.getBlobLocator() ) ) ); s.delete( entity ); s.getTransaction().commit(); diff --git a/hibernate-core/src/test/java/org/hibernate/test/lob/LongByteArrayTest.java b/hibernate-core/src/test/java/org/hibernate/test/lob/LongByteArrayTest.java index fe381c11f2..f35708f864 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/lob/LongByteArrayTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/lob/LongByteArrayTest.java @@ -6,13 +6,14 @@ */ package org.hibernate.test.lob; -import junit.framework.AssertionFailedError; -import org.junit.Assert; -import org.junit.Test; +import java.util.Arrays; import org.hibernate.Session; -import org.hibernate.internal.util.collections.ArrayHelper; + import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Assert; +import org.junit.Test; +import junit.framework.AssertionFailedError; import static org.junit.Assert.assertNull; @@ -120,7 +121,7 @@ public abstract class LongByteArrayTest extends BaseCoreFunctionalTestCase { } public static void assertEquals(byte[] val1, byte[] val2) { - if ( !ArrayHelper.isEquals( val1, val2 ) ) { + if ( !Arrays.equals( val1, val2 ) ) { throw new AssertionFailedError( "byte arrays did not match" ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/test/sql/hand/custom/CustomSQLTestSupport.java b/hibernate-core/src/test/java/org/hibernate/test/sql/hand/custom/CustomSQLTestSupport.java index 6a10f90f44..29478182b8 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/sql/hand/custom/CustomSQLTestSupport.java +++ b/hibernate-core/src/test/java/org/hibernate/test/sql/hand/custom/CustomSQLTestSupport.java @@ -7,21 +7,21 @@ package org.hibernate.test.sql.hand.custom; import java.io.Serializable; +import java.util.Arrays; import java.util.Date; import java.util.Iterator; -import org.junit.Test; - import org.hibernate.LockMode; import org.hibernate.Session; import org.hibernate.Transaction; -import org.hibernate.internal.util.collections.ArrayHelper; + +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.test.sql.hand.Employment; import org.hibernate.test.sql.hand.ImageHolder; import org.hibernate.test.sql.hand.Organization; import org.hibernate.test.sql.hand.Person; import org.hibernate.test.sql.hand.TextHolder; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -145,7 +145,7 @@ public abstract class CustomSQLTestSupport extends BaseCoreFunctionalTestCase { s = openSession(); t = s.beginTransaction(); holder = ( ImageHolder ) s.get( ImageHolder.class, holder.getId() ); - assertTrue( ArrayHelper.isEquals( photo, holder.getPhoto() ) ); + assertTrue( Arrays.equals( photo, holder.getPhoto() ) ); photo = buildLongByteArray( 15000, false ); holder.setPhoto( photo ); s.save( holder ); @@ -155,7 +155,7 @@ public abstract class CustomSQLTestSupport extends BaseCoreFunctionalTestCase { s = openSession(); t = s.beginTransaction(); holder = ( ImageHolder ) s.get( ImageHolder.class, holder.getId() ); - assertTrue( ArrayHelper.isEquals( photo, holder.getPhoto() ) ); + assertTrue( Arrays.equals( photo, holder.getPhoto() ) ); s.delete( holder ); t.commit(); s.close(); diff --git a/hibernate-core/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java b/hibernate-core/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java index 2568524838..e9cf823e92 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java @@ -9,6 +9,7 @@ package org.hibernate.test.sql.hand.query; import java.io.Serializable; import java.math.BigDecimal; import java.math.BigInteger; +import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -29,7 +30,6 @@ import org.hibernate.dialect.H2Dialect; import org.hibernate.dialect.MySQL5Dialect; import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn; import org.hibernate.engine.spi.NamedSQLQueryDefinitionBuilder; -import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.transform.BasicTransformerAdapter; import org.hibernate.transform.DistinctRootEntityResultTransformer; import org.hibernate.transform.Transformers; @@ -867,7 +867,7 @@ public class NativeSQLQueriesTest extends BaseCoreFunctionalTestCase { t = s.beginTransaction(); byte[] photoRead = ( byte[] ) s.createSQLQuery( getPhotosSQL() ) .uniqueResult(); - assertTrue( ArrayHelper.isEquals( photo, photoRead ) ); + assertTrue( Arrays.equals( photo, photoRead ) ); s.delete( holder ); t.commit(); s.close(); diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/instrument/cases/TestLazyPropertyOnPreUpdateExecutable.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/instrument/cases/TestLazyPropertyOnPreUpdateExecutable.java index 889fc5e5c3..c47b854942 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/instrument/cases/TestLazyPropertyOnPreUpdateExecutable.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/instrument/cases/TestLazyPropertyOnPreUpdateExecutable.java @@ -6,12 +6,10 @@ */ package org.hibernate.jpa.test.instrument.cases; +import java.util.Arrays; import javax.persistence.EntityManager; -import org.junit.Test; - import org.hibernate.Hibernate; -import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.jpa.test.instrument.domain.EntityWithLazyProperty; import static org.junit.Assert.assertFalse; @@ -97,7 +95,7 @@ public class TestLazyPropertyOnPreUpdateExecutable extends AbstractExecutable { em.getTransaction().begin(); entity = em.find(EntityWithLazyProperty.class, entity.getId()); assertFalse( Hibernate.isPropertyInitialized( entity, "lazyData") ); - assertTrue( ArrayHelper.isEquals( expected, entity.getLazyData() ) ); + assertTrue( Arrays.equals( expected, entity.getLazyData() ) ); assertTrue( Hibernate.isPropertyInitialized( entity, "lazyData" ) ); em.getTransaction().commit(); em.close();