diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/TypedValue.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/TypedValue.java index 750db84c30..0e772ff9a8 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/TypedValue.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/TypedValue.java @@ -23,6 +23,8 @@ */ package org.hibernate.engine.spi; +import java.io.IOException; +import java.io.ObjectInputStream; import java.io.Serializable; import org.hibernate.EntityMode; @@ -39,19 +41,12 @@ public final class TypedValue implements Serializable { private final Type type; private final Object value; // "transient" is important here -- NaturalIdCacheKey needs to be Serializable - private final transient ValueHolder hashcode; + private transient ValueHolder hashcode; public TypedValue(final Type type, final Object value) { this.type = type; this.value = value; - this.hashcode = new ValueHolder( - new ValueHolder.DeferredInitializer() { - @Override - public Integer initialize() { - return value == null ? 0 : type.getHashCode( value ); - } - } - ); + initTransients(); } /** @@ -90,9 +85,18 @@ public final class TypedValue implements Serializable { && type.isEqual( that.value, value ); } + private void readObject(ObjectInputStream ois) + throws ClassNotFoundException, IOException { + ois.defaultReadObject(); + initTransients(); + } + + private void initTransients() { + this.hashcode = new ValueHolder( new ValueHolder.DeferredInitializer() { + @Override + public Integer initialize() { + return value == null ? 0 : type.getHashCode( value ); + } + } ); + } } - - - - - diff --git a/hibernate-core/src/test/java/org/hibernate/test/serialization/TypedValueSerializationTest.java b/hibernate-core/src/test/java/org/hibernate/test/serialization/TypedValueSerializationTest.java new file mode 100644 index 0000000000..3518ef2382 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/serialization/TypedValueSerializationTest.java @@ -0,0 +1,60 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * JBoss, Home of Professional Open Source + * Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @authors tag. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.hibernate.test.serialization; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import org.hibernate.engine.spi.TypedValue; +import org.hibernate.testing.TestForIssue; +import org.hibernate.type.Type; +import org.junit.Test; + +/** + * @author Brett Meyer + */ +public class TypedValueSerializationTest { + + @Test + @TestForIssue(jiraKey = "HHH-9024") + public void testTypedValueSerialization() throws Exception { + final Type mockType = mock(Type.class); + final String value = "foo"; + final TypedValue typedValue = new TypedValue(mockType, value); + + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(typedValue); + + final ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); + final TypedValue typedValueClone = (TypedValue) ois.readObject(); + + assertEquals(typedValue.hashCode(), typedValueClone.hashCode()); + assertEquals(typedValue.toString(), typedValueClone.toString()); + assertEquals(typedValue.getValue(), typedValueClone.getValue()); + } + +}