From d1980cba1408a5d80dfde43d317d3b5b0a361efd Mon Sep 17 00:00:00 2001 From: Marco Belladelli Date: Mon, 9 Sep 2024 10:58:17 +0200 Subject: [PATCH] HHH-18564 Add test for issue --- .../object/ConvertedClassAttributeTest.java | 119 ++++++++++++++++++ .../converted/converter/object/Status.java | 53 ++++++++ 2 files changed, 172 insertions(+) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/object/ConvertedClassAttributeTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/object/Status.java diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/object/ConvertedClassAttributeTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/object/ConvertedClassAttributeTest.java new file mode 100644 index 0000000000..ae2190ed1d --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/object/ConvertedClassAttributeTest.java @@ -0,0 +1,119 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.mapping.converted.converter.object; + +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.Jira; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Convert; +import jakarta.persistence.Converter; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Marco Belladelli + */ +@DomainModel( annotatedClasses = { + ConvertedClassAttributeTest.EntityWithStatus.class, + Status.class, +} ) +@SessionFactory +@Jira( "https://hibernate.atlassian.net/browse/HHH-18564" ) +public class ConvertedClassAttributeTest { + @Test + public void testConvertedAttributeSelection(SessionFactoryScope scope) { + scope.inTransaction( session -> { + final var resultList = session.createQuery( + "select t.status from EntityWithStatus t", + Status.class + ).getResultList(); + assertThat( resultList ).hasSize( 2 ).containsExactlyInAnyOrder( Status.ONE, Status.TWO ); + } ); + } + + @Test + public void testLiteralPredicateDomainForm(SessionFactoryScope scope) { + scope.inTransaction( session -> { + var result = session.createQuery( + String.format( "select t from EntityWithStatus t where t.status > %s.ONE", Status.class.getName() ), + EntityWithStatus.class + ).getSingleResult(); + assertThat( result.getStatus().getValue() ).isEqualTo( 2 ); + } ); + } + + @Test + public void testLiteralPredicateRelationalForm(SessionFactoryScope scope) { + scope.inTransaction( session -> { + var result = session.createQuery( + "select t from EntityWithStatus t where t.status > 1", + EntityWithStatus.class + ).getSingleResult(); + assertThat( result.getStatus().getValue() ).isEqualTo( 2 ); + } ); + } + + @BeforeAll + public void setUp(SessionFactoryScope scope) { + scope.inTransaction( session -> { + final EntityWithStatus entity1 = new EntityWithStatus(); + entity1.setStatus( Status.ONE ); + session.persist( entity1 ); + final EntityWithStatus entity2 = new EntityWithStatus(); + entity2.setStatus( Status.TWO ); + session.persist( entity2 ); + } ); + } + + @AfterAll + public void tearDown(SessionFactoryScope scope) { + scope.getSessionFactory().getSchemaManager().truncateMappedObjects(); + } + + @Entity( name = "EntityWithStatus" ) + static class EntityWithStatus { + @Id + @GeneratedValue + private Long id; + + @Convert( converter = StatusConverter.class ) + private Status status; + + public Long getId() { + return id; + } + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + } + + @Converter + static class StatusConverter implements AttributeConverter { + @Override + public Integer convertToDatabaseColumn(Status attribute) { + return attribute == null ? null : attribute.getValue(); + } + + @Override + public Status convertToEntityAttribute(Integer dbData) { + return dbData == null ? null : Status.from( dbData ); + } + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/object/Status.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/object/Status.java new file mode 100644 index 0000000000..c862e197d1 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/object/Status.java @@ -0,0 +1,53 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.mapping.converted.converter.object; + +import org.hibernate.annotations.Imported; + +/** + * @author Marco Belladelli + */ +@Imported +public class Status { + public static Status ONE = new Status( 1 ); + public static Status TWO = new Status( 2 ); + + private final int value; + + public Status(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + + public static Status from(int value) { + return new Status( value ); + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + final Status status = (Status) o; + return value == status.value; + } + + @Override + public int hashCode() { + return value; + } + + @Override + public String toString() { + return "Status{" + "value=" + value + '}'; + } +}