Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,23 @@ protected String getResultSetIsNullableLabel() {

@Override
protected int dataTypeCode(String typeName) {
// ORACLE only supports "float" sql type for double precision
// so return code for double for both double and float column types
if ( typeName.equalsIgnoreCase( "float" ) ||
typeName.toLowerCase().startsWith( "double" ) ) {
return Types.DOUBLE;
}
return super.dataTypeCode( typeName );
return switch ( typeName.toLowerCase() ) {
// ORACLE only supports "float" sql type for double precision
// so return code for double for both double and float column types
case "float", "double", "binary_double" -> Types.DOUBLE;
case "timestamp" -> Types.TIMESTAMP;
case "timestamp with time zone", "timestamp with local time zone" -> Types.TIMESTAMP_WITH_TIMEZONE;
case "clob" -> Types.CLOB;
case "blob" -> Types.BLOB;
case "raw" -> Types.VARBINARY;
case "long raw" -> Types.LONGVARBINARY;
case "ref cursor" -> Types.REF_CURSOR;
case "number" -> Types.NUMERIC;
case "date" -> Types.DATE;
case "nvarchar2" -> Types.NVARCHAR;
case "varchar2" -> Types.VARCHAR;
default -> 0;
};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
package org.hibernate.reactive.schema;


import java.net.URL;
import java.util.concurrent.CompletionStage;
import java.util.stream.Stream;

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

Expand All @@ -23,6 +26,7 @@

import io.vertx.junit5.Timeout;
import io.vertx.junit5.VertxTestContext;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
Expand All @@ -34,6 +38,7 @@
import static org.hibernate.reactive.containers.DatabaseConfiguration.DBType.DB2;
import static org.hibernate.reactive.containers.DatabaseConfiguration.DBType.MARIA;
import static org.hibernate.reactive.containers.DatabaseConfiguration.DBType.MYSQL;
import static org.hibernate.reactive.containers.DatabaseConfiguration.DBType.ORACLE;
import static org.hibernate.reactive.testing.ReactiveAssertions.assertThrown;
import static org.hibernate.tool.schema.JdbcMetadataAccessStrategy.GROUPED;
import static org.hibernate.tool.schema.JdbcMetadataAccessStrategy.INDIVIDUALLY;
Expand All @@ -47,7 +52,7 @@
* - TODO: Test that validation fails when a column is the wrong type
*/
@DisabledFor(value = DB2, reason = "We don't have an information extractor. See https://github.com/hibernate/hibernate-reactive/issues/911")
@DisabledFor(value = {MARIA, MYSQL}, reason = "HHH-18869: Schema creation creates an invalid schema")
@DisabledFor(value = { MARIA, MYSQL }, reason = "HHH-18869: Schema creation creates an invalid schema")
public class SchemaValidationTest extends BaseReactiveTest {

static Stream<Arguments> settings() {
Expand Down Expand Up @@ -77,9 +82,18 @@ public void before(VertxTestContext context) {
}

public CompletionStage<Void> setupFactory(String strategy, String type) {
return setupFactory( strategy, type, null );
}

public CompletionStage<Void> setupFactory(String strategy, String type, String importFile) {
Configuration createConf = constructConfiguration( "create", strategy, type );
createConf.addAnnotatedClass( BasicTypesTestEntity.class );

if ( importFile != null ) {
final URL importFileURL = Thread.currentThread()
.getContextClassLoader()
.getResource( importFile );
createConf.setProperty( AvailableSettings.JAKARTA_HBM2DDL_LOAD_SCRIPT_SOURCE, importFileURL.getFile() );
}
// Make sure that the extra table is not in the db
Configuration dropConf = constructConfiguration( "drop", strategy, type );
dropConf.addAnnotatedClass( Extra.class );
Expand All @@ -97,6 +111,21 @@ public void after(VertxTestContext context) {
closeFactory( context );
}

@ParameterizedTest
@MethodSource("settings")
@EnabledFor( ORACLE )
public void testOracleColumnTypeValidation(final String strategy, final String type, VertxTestContext context) {
test(
context, setupFactory( strategy, type, "oracle-SchemaValidationTest.sql" )
.thenCompose( v -> {
Configuration validateConf = constructConfiguration( "validate", strategy, type );
validateConf.addAnnotatedClass( Fruit.class );
new StandardServiceRegistryBuilder().applySettings( validateConf.getProperties() );
return setupSessionFactory( validateConf );
} )
);
}

// When we have created the table, the validation should pass
@ParameterizedTest
@MethodSource("settings")
Expand Down Expand Up @@ -147,4 +176,43 @@ public static class Extra {

private String description;
}

@Entity(name = "Fruit")
public static class Fruit {

@Id
@GeneratedValue
private Integer id;

@Column(name = "something_name", nullable = false, updatable = false)
private String name;

public Fruit() {
}

public Fruit(String name) {
this.name = name;
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "Fruit{" + id + "," + name + '}';
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- Import file for testing schema validation in SchemaValidationTest
drop table if exists Fruit cascade constraints
drop sequence if exists Fruit_SEQ

-- Create the table manually, so that we can check if the validation succeeds
create sequence fruit_seq start with 1 increment by 50;
create table Fruit (id number(10,0) not null, something_name nvarchar2(20) not null, primary key (id))

INSERT INTO fruit(id, something_name) VALUES (1, 'Cherry');
INSERT INTO fruit(id, something_name) VALUES (2, 'Apple');
INSERT INTO fruit(id, something_name) VALUES (3, 'Banana');
ALTER SEQUENCE fruit_seq RESTART start with 4;
Loading