Skip to content

Commit 7ba3e8d

Browse files
committed
HHH-18976 Use a clone-based implementation for all array mutability plans
It's more consistent, and happens to get rid of ArrayMutabilityPlan, which involved an unnecessary use of Array.newInstance. I've also seen claims that clone() performs better than Array.newInstance() due to not having to zero-out the allocated memory, but I doubt that's relevant here.
1 parent 0d69bf8 commit 7ba3e8d

12 files changed

+67
-137
lines changed

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ArrayMutabilityPlan.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212
* are immutable, a shallow copy is enough.
1313
*
1414
* @author Steve Ebersole
15+
*
16+
* @deprecated Use {@link ImmutableObjectArrayMutabilityPlan#get()} for object arrays,
17+
* or implement a dedicated mutability plan for primitive arrays
18+
* (see for example {@link ShortPrimitiveArrayJavaType}'s mutability plan).
1519
*/
20+
@Deprecated
1621
public class ArrayMutabilityPlan<T> extends MutableMutabilityPlan<T> {
1722
public static final ArrayMutabilityPlan INSTANCE = new ArrayMutabilityPlan();
1823

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BooleanPrimitiveArrayJavaType.java

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55
package org.hibernate.type.descriptor.java;
66

7-
import java.io.Serializable;
87
import java.lang.reflect.Array;
98
import java.sql.SQLException;
109
import java.util.ArrayList;
@@ -13,7 +12,6 @@
1312
import java.util.List;
1413

1514
import org.hibernate.HibernateException;
16-
import org.hibernate.SharedSessionContract;
1715
import org.hibernate.engine.jdbc.BinaryStream;
1816
import org.hibernate.engine.jdbc.internal.ArrayBackedBinaryStream;
1917
import org.hibernate.internal.build.AllowReflection;
@@ -185,27 +183,10 @@ else if ( value instanceof Collection<?> collection ) {
185183
throw unknownWrap( value.getClass() );
186184
}
187185

188-
private static class ArrayMutabilityPlan implements MutabilityPlan<boolean[]> {
189-
190-
@Override
191-
public boolean isMutable() {
192-
return true;
193-
}
194-
186+
private static class ArrayMutabilityPlan extends MutableMutabilityPlan<boolean[]> {
195187
@Override
196-
public boolean[] deepCopy(boolean[] value) {
197-
return value == null ? null : value.clone();
188+
protected boolean[] deepCopyNotNull(boolean[] value) {
189+
return value.clone();
198190
}
199-
200-
@Override
201-
public Serializable disassemble(boolean[] value, SharedSessionContract session) {
202-
return deepCopy( value );
203-
}
204-
205-
@Override
206-
public boolean[] assemble(Serializable cached, SharedSessionContract session) {
207-
return deepCopy( (boolean[]) cached );
208-
}
209-
210191
}
211192
}

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ByteArrayJavaType.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class ByteArrayJavaType extends AbstractClassJavaType<Byte[]> {
3030

3131
@SuppressWarnings("unchecked")
3232
public ByteArrayJavaType() {
33-
super( Byte[].class, ArrayMutabilityPlan.INSTANCE, IncomparableComparator.INSTANCE );
33+
super( Byte[].class, ImmutableObjectArrayMutabilityPlan.get(), IncomparableComparator.INSTANCE );
3434
}
3535
@Override
3636
public boolean areEqual(Byte[] one, Byte[] another) {

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CharacterArrayJavaType.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class CharacterArrayJavaType extends AbstractClassJavaType<Character[]> {
2929

3030
@SuppressWarnings("unchecked")
3131
public CharacterArrayJavaType() {
32-
super( Character[].class, ArrayMutabilityPlan.INSTANCE, IncomparableComparator.INSTANCE );
32+
super( Character[].class, ImmutableObjectArrayMutabilityPlan.get(), IncomparableComparator.INSTANCE );
3333
}
3434

3535
@Override

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DoublePrimitiveArrayJavaType.java

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55
package org.hibernate.type.descriptor.java;
66

7-
import java.io.Serializable;
87
import java.lang.reflect.Array;
98
import java.sql.SQLException;
109
import java.util.ArrayList;
@@ -13,7 +12,6 @@
1312
import java.util.List;
1413

1514
import org.hibernate.HibernateException;
16-
import org.hibernate.SharedSessionContract;
1715
import org.hibernate.engine.jdbc.BinaryStream;
1816
import org.hibernate.engine.jdbc.internal.ArrayBackedBinaryStream;
1917
import org.hibernate.internal.build.AllowReflection;
@@ -185,27 +183,10 @@ else if ( value instanceof Collection<?> collection ) {
185183
throw unknownWrap( value.getClass() );
186184
}
187185

188-
private static class ArrayMutabilityPlan implements MutabilityPlan<double[]> {
189-
190-
@Override
191-
public boolean isMutable() {
192-
return true;
193-
}
194-
186+
private static class ArrayMutabilityPlan extends MutableMutabilityPlan<double[]> {
195187
@Override
196-
public double[] deepCopy(double[] value) {
197-
return value == null ? null : value.clone();
188+
protected double[] deepCopyNotNull(double[] value) {
189+
return value.clone();
198190
}
199-
200-
@Override
201-
public Serializable disassemble(double[] value, SharedSessionContract session) {
202-
return deepCopy( value );
203-
}
204-
205-
@Override
206-
public double[] assemble(Serializable cached, SharedSessionContract session) {
207-
return deepCopy( (double[]) cached );
208-
}
209-
210191
}
211192
}

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/FloatPrimitiveArrayJavaType.java

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55
package org.hibernate.type.descriptor.java;
66

7-
import java.io.Serializable;
87
import java.lang.reflect.Array;
98
import java.sql.SQLException;
109
import java.util.ArrayList;
@@ -13,7 +12,6 @@
1312
import java.util.List;
1413

1514
import org.hibernate.HibernateException;
16-
import org.hibernate.SharedSessionContract;
1715
import org.hibernate.engine.jdbc.BinaryStream;
1816
import org.hibernate.engine.jdbc.internal.ArrayBackedBinaryStream;
1917
import org.hibernate.internal.build.AllowReflection;
@@ -185,27 +183,10 @@ else if ( value instanceof Collection<?> collection ) {
185183
throw unknownWrap( value.getClass() );
186184
}
187185

188-
private static class ArrayMutabilityPlan implements MutabilityPlan<float[]> {
189-
190-
@Override
191-
public boolean isMutable() {
192-
return true;
193-
}
194-
186+
private static class ArrayMutabilityPlan extends MutableMutabilityPlan<float[]> {
195187
@Override
196-
public float[] deepCopy(float[] value) {
197-
return value == null ? null : value.clone();
188+
protected float[] deepCopyNotNull(float[] value) {
189+
return value.clone();
198190
}
199-
200-
@Override
201-
public Serializable disassemble(float[] value, SharedSessionContract session) {
202-
return deepCopy( value );
203-
}
204-
205-
@Override
206-
public float[] assemble(Serializable cached, SharedSessionContract session) {
207-
return deepCopy( (float[]) cached );
208-
}
209-
210191
}
211192
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.type.descriptor.java;
6+
7+
/**
8+
* A mutability plan for mutable arrays of immutable, non-primitive objects.
9+
* <p>
10+
* Since the elements themselves are immutable, the deep copy can be implemented with a shallow copy.
11+
*
12+
* @author Steve Ebersole
13+
*/
14+
public final class ImmutableObjectArrayMutabilityPlan<T> extends MutableMutabilityPlan<T[]> {
15+
@SuppressWarnings("rawtypes")
16+
private static final ImmutableObjectArrayMutabilityPlan INSTANCE = new ImmutableObjectArrayMutabilityPlan();
17+
18+
@SuppressWarnings("unchecked") // Works for any T
19+
public static <T> ImmutableObjectArrayMutabilityPlan<T> get() {
20+
return (ImmutableObjectArrayMutabilityPlan<T>) INSTANCE;
21+
}
22+
23+
public T[] deepCopyNotNull(T[] value) {
24+
return value.clone();
25+
}
26+
}

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/IntegerPrimitiveArrayJavaType.java

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55
package org.hibernate.type.descriptor.java;
66

7-
import java.io.Serializable;
87
import java.lang.reflect.Array;
98
import java.sql.SQLException;
109
import java.util.ArrayList;
@@ -13,7 +12,6 @@
1312
import java.util.List;
1413

1514
import org.hibernate.HibernateException;
16-
import org.hibernate.SharedSessionContract;
1715
import org.hibernate.engine.jdbc.BinaryStream;
1816
import org.hibernate.engine.jdbc.internal.ArrayBackedBinaryStream;
1917
import org.hibernate.internal.build.AllowReflection;
@@ -185,27 +183,10 @@ else if ( value instanceof Collection<?> collection ) {
185183
throw unknownWrap( value.getClass() );
186184
}
187185

188-
private static class ArrayMutabilityPlan implements MutabilityPlan<int[]> {
189-
190-
@Override
191-
public boolean isMutable() {
192-
return true;
193-
}
194-
186+
private static class ArrayMutabilityPlan extends MutableMutabilityPlan<int[]> {
195187
@Override
196-
public int[] deepCopy(int[] value) {
197-
return value == null ? null : value.clone();
188+
protected int[] deepCopyNotNull(int[] value) {
189+
return value.clone();
198190
}
199-
200-
@Override
201-
public Serializable disassemble(int[] value, SharedSessionContract session) {
202-
return deepCopy( value );
203-
}
204-
205-
@Override
206-
public int[] assemble(Serializable cached, SharedSessionContract session) {
207-
return deepCopy( (int[]) cached );
208-
}
209-
210191
}
211192
}

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LongPrimitiveArrayJavaType.java

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55
package org.hibernate.type.descriptor.java;
66

7-
import java.io.Serializable;
87
import java.lang.reflect.Array;
98
import java.sql.SQLException;
109
import java.util.ArrayList;
@@ -13,7 +12,6 @@
1312
import java.util.List;
1413

1514
import org.hibernate.HibernateException;
16-
import org.hibernate.SharedSessionContract;
1715
import org.hibernate.engine.jdbc.BinaryStream;
1816
import org.hibernate.engine.jdbc.internal.ArrayBackedBinaryStream;
1917
import org.hibernate.internal.build.AllowReflection;
@@ -185,27 +183,10 @@ else if ( value instanceof Collection<?> collection ) {
185183
throw unknownWrap( value.getClass() );
186184
}
187185

188-
private static class ArrayMutabilityPlan implements MutabilityPlan<long[]> {
189-
190-
@Override
191-
public boolean isMutable() {
192-
return true;
193-
}
194-
186+
private static class ArrayMutabilityPlan extends MutableMutabilityPlan<long[]> {
195187
@Override
196-
public long[] deepCopy(long[] value) {
197-
return value == null ? null : value.clone();
188+
protected long[] deepCopyNotNull(long[] value) {
189+
return value.clone();
198190
}
199-
200-
@Override
201-
public Serializable disassemble(long[] value, SharedSessionContract session) {
202-
return deepCopy( value );
203-
}
204-
205-
@Override
206-
public long[] assemble(Serializable cached, SharedSessionContract session) {
207-
return deepCopy( (long[]) cached );
208-
}
209-
210191
}
211192
}

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/PrimitiveByteArrayJavaType.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@ public class PrimitiveByteArrayJavaType extends AbstractClassJavaType<byte[]>
2828
implements VersionJavaType<byte[]> {
2929
public static final PrimitiveByteArrayJavaType INSTANCE = new PrimitiveByteArrayJavaType();
3030

31-
@SuppressWarnings("unchecked")
3231
public PrimitiveByteArrayJavaType() {
33-
super( byte[].class, ArrayMutabilityPlan.INSTANCE, RowVersionComparator.INSTANCE );
32+
super( byte[].class, new ArrayMutabilityPlan(), RowVersionComparator.INSTANCE );
3433
}
3534

3635
@Override
@@ -160,4 +159,11 @@ public byte[] next(
160159
Integer scale, SharedSessionContractImplementor session) {
161160
return current;
162161
}
162+
163+
private static class ArrayMutabilityPlan extends MutableMutabilityPlan<byte[]> {
164+
@Override
165+
protected byte[] deepCopyNotNull(byte[] value) {
166+
return value.clone();
167+
}
168+
}
163169
}

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/PrimitiveCharacterArrayJavaType.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public class PrimitiveCharacterArrayJavaType extends AbstractClassJavaType<char[
2424

2525
@SuppressWarnings("unchecked")
2626
protected PrimitiveCharacterArrayJavaType() {
27-
super( char[].class, ArrayMutabilityPlan.INSTANCE, IncomparableComparator.INSTANCE );
27+
super( char[].class, new ArrayMutabilityPlan(), IncomparableComparator.INSTANCE );
2828
}
2929

3030
public String toString(char[] value) {
@@ -103,4 +103,11 @@ else if ( value instanceof Character character ) {
103103
public <X> char[] coerce(X value, CoercionContext coercionContext) {
104104
return wrap( value, null );
105105
}
106+
107+
private static class ArrayMutabilityPlan extends MutableMutabilityPlan<char[]> {
108+
@Override
109+
protected char[] deepCopyNotNull(char[] value) {
110+
return value.clone();
111+
}
112+
}
106113
}

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ShortPrimitiveArrayJavaType.java

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55
package org.hibernate.type.descriptor.java;
66

7-
import java.io.Serializable;
87
import java.lang.reflect.Array;
98
import java.sql.SQLException;
109
import java.util.ArrayList;
@@ -13,7 +12,6 @@
1312
import java.util.List;
1413

1514
import org.hibernate.HibernateException;
16-
import org.hibernate.SharedSessionContract;
1715
import org.hibernate.engine.jdbc.BinaryStream;
1816
import org.hibernate.engine.jdbc.internal.ArrayBackedBinaryStream;
1917
import org.hibernate.internal.build.AllowReflection;
@@ -185,27 +183,10 @@ else if ( value instanceof Collection<?> collection ) {
185183
throw unknownWrap( value.getClass() );
186184
}
187185

188-
private static class ArrayMutabilityPlan implements MutabilityPlan<short[]> {
189-
190-
@Override
191-
public boolean isMutable() {
192-
return true;
193-
}
194-
186+
private static class ArrayMutabilityPlan extends MutableMutabilityPlan<short[]> {
195187
@Override
196-
public short[] deepCopy(short[] value) {
197-
return value == null ? null : value.clone();
188+
protected short[] deepCopyNotNull(short[] value) {
189+
return value.clone();
198190
}
199-
200-
@Override
201-
public Serializable disassemble(short[] value, SharedSessionContract session) {
202-
return deepCopy( value );
203-
}
204-
205-
@Override
206-
public short[] assemble(Serializable cached, SharedSessionContract session) {
207-
return deepCopy( (short[]) cached );
208-
}
209-
210191
}
211192
}

0 commit comments

Comments
 (0)