HHH-17507 HHH-17574 Fixed wrap() & unwrap() & updated unit tests

This commit is contained in:
H.Lo 2023-12-25 15:39:26 +01:00 committed by Christian Beikov
parent ec60a5ae1c
commit 3ca2bd8206
4 changed files with 254 additions and 37 deletions

View File

@ -39,6 +39,9 @@ public class CurrencyJavaType extends AbstractClassJavaType<Currency> {
if ( value == null ) {
return null;
}
if ( Currency.class.isAssignableFrom( type ) ) {
return (X) value;
}
if ( String.class.isAssignableFrom( type ) ) {
return (X) value.getCurrencyCode();
}
@ -50,6 +53,9 @@ public class CurrencyJavaType extends AbstractClassJavaType<Currency> {
if ( value == null ) {
return null;
}
if ( value instanceof Currency ) {
return (Currency) value;
}
if (value instanceof String) {
return Currency.getInstance( (String) value );
}

View File

@ -72,6 +72,10 @@ public class YearJavaType extends AbstractClassJavaType<Year> {
return null;
}
if ( value instanceof Year) {
return (Year) value;
}
if ( value instanceof Number ) {
return Year.of( ( (Number) value ).intValue() );
}

View File

@ -6,23 +6,39 @@
*/
package org.hibernate.orm.test.mapping.basic;
import java.sql.Types;
import java.util.Currency;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import org.assertj.core.api.Assertions;
import org.hibernate.HibernateException;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NonContextualLobCreator;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
import org.hibernate.metamodel.mapping.internal.BasicValuedCollectionPart;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.orm.test.mapping.type.java.YearMappingTests;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.CurrencyJavaType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.junit.jupiter.api.Test;
import java.sql.Types;
import java.time.Year;
import java.util.Currency;
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
@ -31,6 +47,7 @@ import static org.hamcrest.Matchers.equalTo;
*/
@DomainModel(annotatedClasses = CurrencyMappingTests.EntityWithCurrency.class)
@SessionFactory
@JiraKey("HHH-17574")
public class CurrencyMappingTests {
@Test
@ -46,17 +63,129 @@ public class CurrencyMappingTests {
assertThat(jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo(Currency.class));
assertThat( jdbcMapping.getJdbcType(), equalTo( jdbcRegistry.getDescriptor( Types.VARCHAR)));
final EntityWithCurrency entity = createEntityWithCurrency();
scope.inTransaction(
(session) -> {
session.persist(new EntityWithCurrency(1, Currency.getInstance("USD")));
}
(session) -> session.persist(entity)
);
scope.inTransaction(
(session) -> session.find(EntityWithCurrency.class, 1)
(session) -> session.find(EntityWithCurrency.class, 1)
);
}
@Test
public void basicAssertions(final SessionFactoryScope scope) {
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
final JdbcTypeRegistry jdbcTypeRegistry = sessionFactory.getTypeConfiguration().getJdbcTypeRegistry();
final EntityPersister entityDescriptor = sessionFactory.getMappingMetamodel().getEntityDescriptor(
EntityWithCurrency.class );
{
final BasicAttributeMapping currencyAttribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping(
"currency");
Assertions.assertThat(currencyAttribute.getJdbcMapping().getJdbcType())
.isEqualTo(jdbcTypeRegistry.getDescriptor(Types.VARCHAR));
Assertions.assertThat(currencyAttribute.getJdbcMapping().getJavaTypeDescriptor().getJavaTypeClass()).isEqualTo(
Currency.class );
}
{
final PluralAttributeMapping currenciesAttribute = (PluralAttributeMapping) entityDescriptor.findAttributeMapping(
"currencies" );
final BasicValuedCollectionPart elementDescriptor = (BasicValuedCollectionPart) currenciesAttribute.getElementDescriptor();
Assertions.assertThat( elementDescriptor.getJdbcMapping().getJdbcType() )
.isEqualTo( jdbcTypeRegistry.getDescriptor( Types.VARCHAR ) );
Assertions.assertThat( elementDescriptor.getJdbcMapping().getJavaTypeDescriptor().getJavaTypeClass() ).isEqualTo(
Currency.class );
}
}
@Test
public void testUnwrapPass() {
final CurrencyJavaType currencyJavaType = new CurrencyJavaType();
final Currency currency = Currency.getInstance("CHF");
{
final Currency c = currencyJavaType.unwrap(currency, Currency.class, null);
Assertions.assertThat( c ).isEqualTo( currency );
}
{
final String c = currencyJavaType.unwrap(currency, String.class, null);
Assertions.assertThat( c ).isEqualTo( "CHF" );
}
}
@Test
public void testUnwrapFail() {
final CurrencyJavaType currencyJavaType = new CurrencyJavaType();
final Currency currency = Currency.getInstance("CHF");
{
Assertions.assertThatThrownBy( () ->
currencyJavaType.unwrap(currency, Boolean.class, null)
).isInstanceOf( HibernateException.class );
}
}
@Test
public void testWrapPass() {
final CurrencyJavaType currencyJavaType = new CurrencyJavaType();
{
final Currency usingNull = currencyJavaType.wrap(null, null);
Assertions.assertThat(usingNull).isNull();
}
{
final Currency usingString = currencyJavaType.wrap("CHF", null);
Assertions.assertThat(usingString).isNotNull();
}
{
final Currency usingCurrency = currencyJavaType.wrap(Currency.getInstance("CHF"), null);
Assertions.assertThat(usingCurrency).isNotNull();
}
}
@Test
public void testWrapFail() {
final CurrencyJavaType currencyJavaType = new CurrencyJavaType();
{
final String usingEmptyString = "";
Assertions.assertThatThrownBy(() ->
currencyJavaType.wrap(usingEmptyString, null)
).isInstanceOf(IllegalArgumentException.class);
}
{
final Integer usingInteger = Integer.valueOf(269);
Assertions.assertThatThrownBy(() ->
currencyJavaType.wrap(usingInteger, null)
).isInstanceOf(HibernateException.class);
}
{
final CurrencyJavaType usingSelf = new CurrencyJavaType();
Assertions.assertThatThrownBy(() ->
currencyJavaType.wrap(usingSelf, null)
).isInstanceOf(HibernateException.class);
}
}
@Test
public void testUsage(final SessionFactoryScope scope) {
final EntityWithCurrency entity = createEntityWithCurrency();
scope.inTransaction((session) -> session.persist(entity));
try {
scope.inTransaction(session -> session.createQuery("from EntityWithCurrency", EntityWithCurrency.class).list());
}
finally {
scope.inTransaction( session -> session.remove( entity ) );
}
}
private static EntityWithCurrency createEntityWithCurrency() {
final Currency currency = Currency.getInstance("USD");
final Set<Currency> currencies = new HashSet<>();
currencies.add(Currency.getInstance("CHF"));
currencies.add(Currency.getInstance("EUR"));
return new EntityWithCurrency( 1, currency, currencies );
}
@Entity(name = "EntityWithCurrency")
@Table(name = "EntityWithCurrency")
public static class EntityWithCurrency {
@ -68,12 +197,18 @@ public class CurrencyMappingTests {
private Currency currency;
//end::basic-Currency-example[]
public EntityWithCurrency() {
@ElementCollection
private Set<Currency> currencies;
public EntityWithCurrency() {
//
}
public EntityWithCurrency(Integer id, Currency currency) {
this.id = id;
this.currency = currency;
}
public EntityWithCurrency(final Integer id, final Currency currency, final Set<Currency> currencies) {
this.id = id;
this.currency = currency;
this.currencies = currencies;
}
}
}

View File

@ -6,40 +6,33 @@
*/
package org.hibernate.orm.test.mapping.type.java;
import java.sql.Types;
import java.time.Year;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import jakarta.persistence.*;
import org.assertj.core.api.Assertions;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
import org.hibernate.metamodel.mapping.internal.BasicValuedCollectionPart;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.YearJavaType;
import org.junit.jupiter.api.Test;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.MapKeyColumn;
import jakarta.persistence.Table;
import java.sql.Types;
import java.time.Year;
import java.time.format.DateTimeParseException;
import java.util.*;
import static org.assertj.core.api.Assertions.assertThat;
@DomainModel( annotatedClasses = YearMappingTests.YearMappingTestEntity.class )
@SessionFactory
@JiraKey( "HHH-10558" )
@JiraKey( "HHH-17507" )
public class YearMappingTests {
@Test
public void basicAssertions(SessionFactoryScope scope) {
@ -69,20 +62,98 @@ public class YearMappingTests {
@Test
public void testUsage(SessionFactoryScope scope) {
final YearMappingTestEntity entity = new YearMappingTestEntity( 1, "one", Year.now() );
final YearMappingTestEntity entity1 = new YearMappingTestEntity( 1, "one", Year.now() );
final YearMappingTestEntity entity2 = new YearMappingTestEntity( 2, "two", Year.parse( "+10000" ) );
scope.inTransaction( (session) -> {
session.save( entity );
session.save( entity2 );
session.persist( entity1 );
session.persist( entity2 );
} );
try {
scope.inTransaction( (session) -> session.createQuery( "from YearMappingTestEntity" ).list() );
scope.inTransaction( (session) -> session.createQuery( "from YearMappingTestEntity", YearMappingTestEntity.class ).list() );
}
finally {
scope.inTransaction( session -> session.delete( entity ) );
scope.inTransaction( session -> session.delete( entity2 ) );
scope.inTransaction( session -> session.remove( entity1 ) );
scope.inTransaction( session -> session.remove( entity2 ) );
}
}
@Test
public void testUnwrapPass() {
final YearJavaType yearJavaType = new YearJavaType();
final Year year = Year.of(1943);
{
final Year y = yearJavaType.unwrap(year, Year.class, null);
Assertions.assertThat( y ).isEqualTo( year );
}
{
final Integer y = yearJavaType.unwrap(year, Integer.class, null);
Assertions.assertThat( y ).isEqualTo( Integer.valueOf( 1943 ) );
}
{
final Long y = yearJavaType.unwrap(year, Long.class, null);
Assertions.assertThat( y ).isEqualTo( Long.valueOf( 1943L ) );
}
{
final String y = yearJavaType.unwrap(year, String.class, null);
Assertions.assertThat( y ).isEqualTo( "1943" );
}
{
final Object y = yearJavaType.unwrap(year, Object.class, null);
Assertions.assertThat( y.toString() ).isEqualTo( "1943" );
}
}
@Test
public void testUnwrapFail() {
final YearJavaType yearJavaType = new YearJavaType();
final Year year = Year.of(1943);
{
Assertions.assertThatThrownBy( () ->
yearJavaType.unwrap(year, Boolean.class, null)
).isInstanceOf( HibernateException.class );
}
}
@Test
public void testWrapPass() {
final YearJavaType yearJavaType = new YearJavaType();
{
final Year usingNull = yearJavaType.wrap( null, null );
Assertions.assertThat( usingNull ).isNull();
}
{
final Year usingNumber = yearJavaType.wrap( 1943, null );
Assertions.assertThat( usingNumber ).isNotNull();
}
{
final Year usingNegative = yearJavaType.wrap( -1, null );
Assertions.assertThat( usingNegative ).isNotNull();
}
{
final Year usingString = yearJavaType.wrap( "1943", null );
Assertions.assertThat( usingString ).isNotNull();
}
{
final Year usingYear = yearJavaType.wrap( Year.of( 1943), null );
Assertions.assertThat( usingYear ).isNotNull();
}
}
@Test
public void testWrapFail() {
final YearJavaType yearJavaType = new YearJavaType();
{
final String usingEmptyString = "";
Assertions.assertThatThrownBy(() ->
yearJavaType.wrap( usingEmptyString, null )
).isInstanceOf(DateTimeParseException.class);
}
{
final Date usingDate = new Date();
Assertions.assertThatThrownBy(() ->
yearJavaType.wrap( usingDate, null )
).isInstanceOf(HibernateException.class);
}
}
@ -156,4 +227,5 @@ public class YearMappingTests {
this.countByYear = countByYear;
}
}
}