From 64c39691fff22c1cf474ac817c9df8ce6c07b48c Mon Sep 17 00:00:00 2001 From: Nathan Xu Date: Fri, 15 Apr 2022 11:12:57 -0400 Subject: [PATCH] HHH-15211 fix embeddable basic attribute converter hash code bug --- .../type/AbstractStandardBasicType.java | 2 +- .../AttributeConverterTypeAdapter.java | 8 +++- ...ctionEmbeddableElementConversionTest.java} | 47 ++++++++++++------- 3 files changed, 39 insertions(+), 18 deletions(-) rename hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/{embeddable/EmbeddableTests.java => CollectionEmbeddableElementConversionTest.java} (75%) diff --git a/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java b/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java index 3ee5ea01d5..3e4dcacc31 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java @@ -161,7 +161,7 @@ public abstract class AbstractStandardBasicType @Override @SuppressWarnings("unchecked") - public final int getHashCode(Object x) { + public int getHashCode(Object x) { return javaType.extractHashCode( (T) x ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/AttributeConverterTypeAdapter.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/AttributeConverterTypeAdapter.java index aa828a9947..0f1bfa517e 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/AttributeConverterTypeAdapter.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/AttributeConverterTypeAdapter.java @@ -88,7 +88,7 @@ public class AttributeConverterTypeAdapter extends AbstractSingleColumnStanda return relationalJtd; } - public JpaAttributeConverter getAttributeConverter() { + public JpaAttributeConverter getAttributeConverter() { return attributeConverter; } @@ -121,6 +121,12 @@ public class AttributeConverterTypeAdapter extends AbstractSingleColumnStanda return ( (JavaType) getDomainJtd() ).areEqual( one, another ); } + @Override + public int getHashCode(Object x) { + //noinspection unchecked + return getDomainJtd().extractHashCode( (T) x ); + } + @Override public String toString() { return description; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/embeddable/EmbeddableTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionEmbeddableElementConversionTest.java similarity index 75% rename from hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/embeddable/EmbeddableTests.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionEmbeddableElementConversionTest.java index 74f34ff2a7..e8cba555d3 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/embeddable/EmbeddableTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionEmbeddableElementConversionTest.java @@ -4,7 +4,7 @@ * 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.orm.test.mapping.converted.converter.elementCollection.embeddable; +package org.hibernate.orm.test.mapping.converted.converter.elementCollection; import java.math.BigDecimal; import java.util.ArrayList; @@ -15,6 +15,8 @@ import org.hibernate.testing.TestForIssue; import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import jakarta.persistence.AttributeConverter; @@ -23,7 +25,6 @@ import jakarta.persistence.ElementCollection; import jakarta.persistence.Embeddable; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; /** @@ -32,35 +33,50 @@ import jakarta.persistence.Id; */ @DomainModel(annotatedClasses = { - EmbeddableTests.ProductEntity.class, - EmbeddableTests.MyBigDecimalConverter.class + CollectionEmbeddableElementConversionTest.ProductEntity.class, + CollectionEmbeddableElementConversionTest.MyBigDecimalConverter.class }) @SessionFactory @TestForIssue(jiraKey = "HHH-15211") -class EmbeddableTests { +class CollectionEmbeddableElementConversionTest { - @Test - void testNoClassCastExceptionThrown(SessionFactoryScope scope) { - final ProductEntity entity = new ProductEntity(); + @BeforeEach + void setUp(SessionFactoryScope scope) { + final ProductEntity entity = new ProductEntity( 1 ); entity.prices = Collections.singletonList( new ProductPrice( new MyBigDecimal( 100.0 ) ) ); - final Integer productId = scope.fromTransaction( session -> { + scope.fromTransaction( session -> { session.persist( entity ); return entity.productId; } ); + } - // without fixing, the following statement would thrown "ClassCastException" + @Test + void testNoClassCastExceptionThrown(SessionFactoryScope scope) { scope.inTransaction( session -> session.get( ProductEntity.class, - productId + 1 ) ); } + @AfterEach + void tearDown(SessionFactoryScope scope) { + scope.inTransaction( + (session) -> session.createQuery( "delete ProductEntity" ).executeUpdate() + ); + } + @Entity(name = "ProductEntity") static class ProductEntity { @Id - @GeneratedValue Integer productId; + ProductEntity() { + } + + ProductEntity(Integer productId) { + this.productId = productId; + } + @ElementCollection(fetch = FetchType.EAGER) List prices = new ArrayList<>(); } @@ -69,7 +85,9 @@ class EmbeddableTests { static class ProductPrice { MyBigDecimal price; - ProductPrice() {} + ProductPrice() { + } + ProductPrice(MyBigDecimal price) { this.price = price; } @@ -95,9 +113,6 @@ class EmbeddableTests { return new MyBigDecimal( dbData.doubleValue() ); } - public MyBigDecimalConverter() { - System.out.println( "Registered MyBigDecimalConverter" ); - } } }