Skip to content

Commit

Permalink
[#1641] tests for @array annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
blafond committed Feb 5, 2024
1 parent dc3d286 commit 6ab0530
Show file tree
Hide file tree
Showing 8 changed files with 371 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ class DB2Database implements TestableDatabase {
expectedDBTypeForClass.put( Character.class, "CHARACTER" );
expectedDBTypeForClass.put( char.class, "CHARACTER" );
expectedDBTypeForClass.put( String.class, "VARCHAR" );
expectedDBTypeForClass.put( String[].class, "VARBINARY" );
expectedDBTypeForClass.put( Long[].class, "VARBINARY" );
expectedDBTypeForClass.put( BigDecimal[].class, "VARBINARY" );
expectedDBTypeForClass.put( BigInteger[].class, "VARBINARY" );
expectedDBTypeForClass.put( Boolean[].class, "VARBINARY" );
}}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ class MSSQLServerDatabase implements TestableDatabase {
expectedDBTypeForClass.put( Character.class, "char" );
expectedDBTypeForClass.put( char.class, "char" );
expectedDBTypeForClass.put( String.class, "varchar" );
expectedDBTypeForClass.put( String[].class, "varbinary" );
expectedDBTypeForClass.put( Long[].class, "varbinary" );
expectedDBTypeForClass.put( BigDecimal[].class, "varbinary" );
expectedDBTypeForClass.put( BigInteger[].class, "varbinary" );
expectedDBTypeForClass.put( Boolean[].class, "varbinary" );
}}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ class MySQLDatabase implements TestableDatabase {
expectedDBTypeForClass.put( Character.class, "char" );
expectedDBTypeForClass.put( char.class, "char" );
expectedDBTypeForClass.put( String.class, "varchar" );
expectedDBTypeForClass.put( String[].class, "varbinary" );
expectedDBTypeForClass.put( Long[].class, "varbinary" );
expectedDBTypeForClass.put( BigDecimal[].class, "varbinary" );
expectedDBTypeForClass.put( BigInteger[].class, "varbinary" );
expectedDBTypeForClass.put( Boolean[].class, "varbinary" );
}};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ class OracleDatabase implements TestableDatabase {
expectedDBTypeForClass.put( Character.class, "CHAR" );
expectedDBTypeForClass.put( char.class, "CHAR" );
expectedDBTypeForClass.put( String.class, "VARCHAR2" );
expectedDBTypeForClass.put( String[].class, "STRINGARRAY" );
expectedDBTypeForClass.put( Long[].class, "LONGARRAY" );
expectedDBTypeForClass.put( BigDecimal[].class, "BIGDECIMALARRAY" );
expectedDBTypeForClass.put( BigInteger[].class, "BIGINTEGERARRAY" );
expectedDBTypeForClass.put( Boolean[].class, "BOOLEANARRAY" );

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ class PostgreSQLDatabase implements TestableDatabase {
expectedDBTypeForClass.put( Character.class, "character" );
expectedDBTypeForClass.put( char.class, "character" );
expectedDBTypeForClass.put( String.class, "character varying" );
expectedDBTypeForClass.put( String[].class, "ARRAY" );
expectedDBTypeForClass.put( Long[].class, "ARRAY" );
expectedDBTypeForClass.put( BigDecimal[].class, "ARRAY" );
expectedDBTypeForClass.put( BigInteger[].class, "ARRAY" );
expectedDBTypeForClass.put( Boolean[].class, "ARRAY" );
}}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* Hibernate, Relational Persistence for Idiomatic Java
*
* SPDX-License-Identifier: Apache-2.0
* Copyright: Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.reactive.schema;

import java.math.BigDecimal;
import java.math.BigInteger;

import org.hibernate.annotations.Array;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.Version;


@Entity(name = "ArrayTypesTestEntity")
@Table(name = ArrayTypesTestEntity.TABLE_NAME)
public class ArrayTypesTestEntity {

public static final String TABLE_NAME = "ARRAY_TYPES_TABLE";

@Id
@GeneratedValue
Integer id;
@Version
Integer version;

String[] stringArray;

@Array( length = 5 )
String[] stringArrayAnnotated;

Long[] longArray;

@Array( length = 5 )
Long[] longArrayAnnotated;

BigDecimal[] bigDecimalArray;

@Array( length = 5 )
BigDecimal[] bigDecimalArrayAnnotated;

BigInteger[] bigIntegerArray;

@Array( length = 5 )
BigInteger[] bigIntegerArrayAnnotated;

Boolean[] fieldBooleanArray;

@Array( length = 5 )
Boolean[] fieldBooleanArrayAnnotated;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/* Hibernate, Relational Persistence for Idiomatic Java
*
* SPDX-License-Identifier: Apache-2.0
* Copyright: Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.reactive.schema;


import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.reactive.BaseReactiveTest;
import org.hibernate.reactive.annotations.DisabledFor;
import org.hibernate.reactive.provider.Settings;
import org.hibernate.tool.schema.spi.SchemaManagementException;

import org.junit.jupiter.api.AfterEach;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import io.vertx.junit5.Timeout;
import io.vertx.junit5.VertxTestContext;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

import static java.util.concurrent.TimeUnit.MINUTES;
import static org.hibernate.reactive.containers.DatabaseConfiguration.DBType.DB2;
import static org.hibernate.tool.schema.JdbcMetadaAccessStrategy.GROUPED;
import static org.hibernate.tool.schema.JdbcMetadaAccessStrategy.INDIVIDUALLY;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

/**
* Test schema validation at startup for all the supported types:
* - Missing table validation error
* - No validation error when everything is fine
* - TODO: Missing column
* - TODO: Wrong column type
*/
@DisabledFor(value = DB2, reason = "No InformationExtractor for Dialect [org.hibernate.dialect.DB2Dialect..]")
public abstract class SchemaArrayTypesValidationTestBase extends BaseReactiveTest {

public static class IndividuallyStrategyTest extends SchemaArrayTypesValidationTestBase {

@Override
protected Configuration constructConfiguration(String hbm2DdlOption) {
final Configuration configuration = super.constructConfiguration( hbm2DdlOption );
configuration.setProperty( Settings.HBM2DDL_JDBC_METADATA_EXTRACTOR_STRATEGY, INDIVIDUALLY.toString() );
configuration.setProperty( Settings.SHOW_SQL, System.getProperty( Settings.SHOW_SQL, "true" ) );
return configuration;
}
}

public static class GroupedStrategyTest extends SchemaArrayTypesValidationTestBase {

@Override
protected Configuration constructConfiguration(String hbm2DdlOption) {
final Configuration configuration = super.constructConfiguration( hbm2DdlOption );
configuration.setProperty( Settings.HBM2DDL_JDBC_METADATA_EXTRACTOR_STRATEGY, GROUPED.toString() );
configuration.setProperty( Settings.SHOW_SQL, System.getProperty( Settings.SHOW_SQL, "true" ) );
return configuration;
}
}

protected Configuration constructConfiguration(String action) {
Configuration configuration = super.constructConfiguration();
configuration.setProperty( Settings.HBM2DDL_JDBC_METADATA_EXTRACTOR_STRATEGY, INDIVIDUALLY.toString() );
configuration.setProperty( Settings.HBM2DDL_AUTO, action );
return configuration;
}

@BeforeEach
@Override
public void before(VertxTestContext context) {
Configuration createConf = constructConfiguration( "create" );
createConf.addAnnotatedClass( ArrayTypesTestEntity.class );

// Make sure that the extra table is not in the db
Configuration dropConf = constructConfiguration( "drop" );
dropConf.addAnnotatedClass( Extra.class );

test( context, setupSessionFactory( dropConf )
.thenCompose( v -> factoryManager.stop() )
.thenCompose( v -> setupSessionFactory( createConf ) )
.thenCompose( v -> factoryManager.stop() )
);
}

@AfterEach
@Override
public void after(VertxTestContext context) {
super.after( context );
closeFactory( context );
}

// When we have created the table, the validation should pass
@Test
@Timeout(value = 10, timeUnit = MINUTES)
public void testValidationSucceeds(VertxTestContext context) {
Configuration validateConf = constructConfiguration( "validate" );
validateConf.addAnnotatedClass( ArrayTypesTestEntity.class );

StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
.applySettings( validateConf.getProperties() );
test( context, setupSessionFactory( validateConf ) );
}

// Validation should fail if a table is missing
@Test
@Timeout(value = 10, timeUnit = MINUTES)
public void testValidationFails(VertxTestContext context) {
Configuration validateConf = constructConfiguration( "validate" );
validateConf.addAnnotatedClass( ArrayTypesTestEntity.class );
// The table mapping this entity shouldn't be in the db
validateConf.addAnnotatedClass( Extra.class );

final String errorMessage = "Schema-validation: missing table [" + Extra.TABLE_NAME + "]";
test( context, setupSessionFactory( validateConf )
.handle( (unused, throwable) -> {
assertNotNull( throwable );
assertEquals( throwable.getClass(), SchemaManagementException.class );
assertEquals( throwable.getMessage(), errorMessage );
return null;
} )
);
}

/**
* An extra entity used for validation,
* it should not be created at start up
*/
@Entity(name = "Extra")
@Table(name = Extra.TABLE_NAME)
public static class Extra {
public static final String TABLE_NAME = "EXTRA_TABLE";
@Id
@GeneratedValue
private Integer id;

private String description;
}
}
Loading

0 comments on commit 6ab0530

Please sign in to comment.