diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/AbstractHANADialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/AbstractHANADialect.java
index 314559506f..41cf9f183f 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/AbstractHANADialect.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/AbstractHANADialect.java
@@ -63,18 +63,19 @@ import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* An abstract base class for HANA dialects.
* SAP HANA Reference
- * This dialect is currently configured to not create foreign keys by
- * returning the empty string from {@link #getAddForeignKeyConstraintString}
- * since they currently have caveats compared to other databases. This does not
+ *
+ * NOTE: This dialect is currently configured to not create foreign keys by
+ * returning the empty string from {@link #getAddForeignKeyConstraintString} since they currently have caveats compared
+ * to other databases. This does not
* affect using this dialect with your own DDL scripts which use foreign keys.
- *
+ *
* @author Andrew Clemons
*/
public abstract class AbstractHANADialect extends Dialect {
private static class CloseSuppressingReader extends FilterReader {
- protected CloseSuppressingReader( final Reader in ) {
- super(in);
+ protected CloseSuppressingReader(final Reader in) {
+ super( in );
}
@Override
@@ -91,56 +92,58 @@ public abstract class AbstractHANADialect extends Dialect {
// using non-contexual lob creation and HANA then closes our StringReader.
// see test case LobLocatorTest
- private static final ClobTypeDescriptor HANA_CLOB_STREAM_BINDING =
- new ClobTypeDescriptor() {
- /** serial version uid. */
- private static final long serialVersionUID = -379042275442752102L;
-
- @Override
- public BasicBinder getClobBinder( final JavaTypeDescriptor javaTypeDescriptor ) {
- return new BasicBinder( javaTypeDescriptor, this ) {
- @Override
- protected void doBind( final PreparedStatement st, final X value, final int index, final WrapperOptions options )
- throws SQLException {
- final CharacterStream characterStream = javaTypeDescriptor.unwrap( value, CharacterStream.class, options );
-
- if (value instanceof ClobImplementer) {
- st.setCharacterStream( index, new CloseSuppressingReader(characterStream.asReader()), characterStream.getLength() );
- } else {
- st.setCharacterStream( index, characterStream.asReader(), characterStream.getLength() );
- }
-
- }
- };
- }
- };
-
- private static final NClobTypeDescriptor HANA_NCLOB_STREAM_BINDING =
- new NClobTypeDescriptor() {
- /** serial version uid. */
- private static final long serialVersionUID = 5651116091681647859L;
+ private static final ClobTypeDescriptor HANA_CLOB_STREAM_BINDING = new ClobTypeDescriptor() {
+ /** serial version uid. */
+ private static final long serialVersionUID = -379042275442752102L;
+ @Override
+ public BasicBinder getClobBinder(final JavaTypeDescriptor javaTypeDescriptor) {
+ return new BasicBinder( javaTypeDescriptor, this ) {
@Override
- public BasicBinder getNClobBinder( final JavaTypeDescriptor javaTypeDescriptor ) {
- return new BasicBinder( javaTypeDescriptor, this ) {
- @Override
- protected void doBind( final PreparedStatement st, final X value, final int index, final WrapperOptions options )
- throws SQLException {
- final CharacterStream characterStream = javaTypeDescriptor.unwrap( value, CharacterStream.class, options );
+ protected void doBind(final PreparedStatement st, final X value, final int index,
+ final WrapperOptions options) throws SQLException {
+ final CharacterStream characterStream = javaTypeDescriptor.unwrap( value, CharacterStream.class,
+ options );
- if (value instanceof NClobImplementer) {
- st.setCharacterStream( index, new CloseSuppressingReader(characterStream.asReader()), characterStream.getLength() );
- } else {
- st.setCharacterStream( index, characterStream.asReader(), characterStream.getLength() );
- }
+ if ( value instanceof ClobImplementer ) {
+ st.setCharacterStream( index, new CloseSuppressingReader( characterStream.asReader() ),
+ characterStream.getLength() );
+ }
+ else {
+ st.setCharacterStream( index, characterStream.asReader(), characterStream.getLength() );
+ }
- }
- };
}
};
+ }
+ };
+
+ private static final NClobTypeDescriptor HANA_NCLOB_STREAM_BINDING = new NClobTypeDescriptor() {
+ /** serial version uid. */
+ private static final long serialVersionUID = 5651116091681647859L;
+
+ @Override
+ public BasicBinder getNClobBinder(final JavaTypeDescriptor javaTypeDescriptor) {
+ return new BasicBinder( javaTypeDescriptor, this ) {
+ @Override
+ protected void doBind(final PreparedStatement st, final X value, final int index,
+ final WrapperOptions options) throws SQLException {
+ final CharacterStream characterStream = javaTypeDescriptor.unwrap( value, CharacterStream.class,
+ options );
+
+ if ( value instanceof NClobImplementer ) {
+ st.setCharacterStream( index, new CloseSuppressingReader( characterStream.asReader() ),
+ characterStream.getLength() );
+ }
+ else {
+ st.setCharacterStream( index, characterStream.asReader(), characterStream.getLength() );
+ }
+
+ }
+ };
+ }
+ };
- /**
- */
public AbstractHANADialect() {
super();
@@ -359,7 +362,6 @@ public abstract class AbstractHANADialect extends Dialect {
return new ConstraintViolationException( message, sqlException, sql, constraintName );
}
-
return null;
}
};
@@ -372,7 +374,7 @@ public abstract class AbstractHANADialect extends Dialect {
@Override
public String getAddColumnString() {
- return "add (";
+ return "add (";
}
@Override
@@ -386,7 +388,7 @@ public abstract class AbstractHANADialect extends Dialect {
}
@Override
- public String getCreateSequenceString( final String sequenceName ) {
+ public String getCreateSequenceString(final String sequenceName) {
return "create sequence " + sequenceName;
}
@@ -401,17 +403,17 @@ public abstract class AbstractHANADialect extends Dialect {
}
@Override
- public String getDropSequenceString( final String sequenceName ) {
+ public String getDropSequenceString(final String sequenceName) {
return "drop sequence " + sequenceName;
}
@Override
- public String getForUpdateString( final String aliases ) {
+ public String getForUpdateString(final String aliases) {
return getForUpdateString() + " of " + aliases;
}
@Override
- public String getForUpdateString( final String aliases, final LockOptions lockOptions ) {
+ public String getForUpdateString(final String aliases, final LockOptions lockOptions) {
LockMode lockMode = lockOptions.getLockMode();
final Iterator> itr = lockOptions.getAliasLockIterator();
while ( itr.hasNext() ) {
@@ -433,13 +435,13 @@ public abstract class AbstractHANADialect extends Dialect {
@Deprecated
@Override
- public String getLimitString( final String sql, final boolean hasOffset ) {
+ public String getLimitString(final String sql, final boolean hasOffset) {
return new StringBuilder( sql.length() + 20 ).append( sql )
.append( hasOffset ? " limit ? offset ?" : " limit ?" ).toString();
}
@Override
- public String getNotExpression( final String expression ) {
+ public String getNotExpression(final String expression) {
return "not (" + expression + ")";
}
@@ -449,17 +451,17 @@ public abstract class AbstractHANADialect extends Dialect {
}
@Override
- public String getSelectSequenceNextValString( final String sequenceName ) {
+ public String getSelectSequenceNextValString(final String sequenceName) {
return sequenceName + ".nextval";
}
@Override
- public String getSequenceNextValString( final String sequenceName ) {
+ public String getSequenceNextValString(final String sequenceName) {
return "select " + getSelectSequenceNextValString( sequenceName ) + " from dummy";
}
@Override
- protected SqlTypeDescriptor getSqlTypeDescriptorOverride( final int sqlCode ) {
+ protected SqlTypeDescriptor getSqlTypeDescriptorOverride(final int sqlCode) {
switch ( sqlCode ) {
case Types.BOOLEAN:
return BitTypeDescriptor.INSTANCE;
@@ -572,12 +574,11 @@ public abstract class AbstractHANADialect extends Dialect {
return false;
}
- /**
- * HANA does support cascade deletes, but since we have overridden the
- * foreign key support, this should also be false.
- */
@Override
public boolean supportsCascadeDelete() {
+ // HANA does support cascade deletes, but since we have (temporarily) overridden the foreign key support,
+ // this should also be false.
+ // TODO: Enable once FK support is solidified and getAddForeignKeyConstraintString is corrected.
return false;
}
@@ -673,13 +674,13 @@ public abstract class AbstractHANADialect extends Dialect {
/**
* Currently disabling foreign key creation when using Hibernate's auto-ddl
- * feature. HANA does allow creating foreign keys, but they do not always
+ * feature. HANA does allow creating foreign keys, but currently they do not always
* behave as expected.
*/
@Override
- public String getAddForeignKeyConstraintString( final String constraintName,
- final String[] foreignKey, final String referencedTable,
- final String[] primaryKey, final boolean referencesPrimaryKey ) {
+ public String getAddForeignKeyConstraintString(final String constraintName, final String[] foreignKey,
+ final String referencedTable, final String[] primaryKey, final boolean referencesPrimaryKey) {
+ // TODO: Re-evaluate in a later HANA release where, hopefully, this has been solidified.
return "";
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/HANAColumnStoreDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/HANAColumnStoreDialect.java
index ad62a219f2..e00c7d89af 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/HANAColumnStoreDialect.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/HANAColumnStoreDialect.java
@@ -27,14 +27,11 @@ package org.hibernate.dialect;
* An SQL dialect for HANA.
* SAP HANA Reference
* Column tables are created by this dialect when using the auto-ddl feature.
- * This dialect was tested with HANA Rev 67 and HDB JDBC 1.00.67.383230.
- *
+ *
* @author Andrew Clemons
*/
public class HANAColumnStoreDialect extends AbstractHANADialect {
- /**
- */
public HANAColumnStoreDialect() {
super();
}
@@ -43,7 +40,4 @@ public class HANAColumnStoreDialect extends AbstractHANADialect {
public String getCreateTableString() {
return "create column table";
}
-
-
-
}
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/HANARowStoreDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/HANARowStoreDialect.java
index 5af28ab210..c17b6eb564 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/HANARowStoreDialect.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/HANARowStoreDialect.java
@@ -27,16 +27,15 @@ package org.hibernate.dialect;
* An SQL dialect for HANA.
* SAP HANA Reference
* Row tables are created by this dialect when using the auto-ddl feature.
- * This dialect was tested with HANA Rev 67 and HDB JDBC 1.00.67.383230.
*
* @author Andrew Clemons
*/
public class HANARowStoreDialect extends AbstractHANADialect {
+
+ // Even though it's currently pointless, provide this structure in case HANA row store merits additional
+ // differences in the future.
- /**
- */
public HANARowStoreDialect() {
super();
}
-
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/dialect/internal/StandardDialectResolver.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/dialect/internal/StandardDialectResolver.java
index b99ae51f1b..50b8a88000 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/dialect/internal/StandardDialectResolver.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/dialect/internal/StandardDialectResolver.java
@@ -208,6 +208,7 @@ public class StandardDialectResolver implements DialectResolver {
}
if ( "HDB".equals( databaseName ) ) {
+ // SAP recommends defaulting to column store.
return new HANAColumnStoreDialect();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Constraint.java b/hibernate-core/src/main/java/org/hibernate/mapping/Constraint.java
index e11fbdd9dd..cfe1869e60 100644
--- a/hibernate-core/src/main/java/org/hibernate/mapping/Constraint.java
+++ b/hibernate-core/src/main/java/org/hibernate/mapping/Constraint.java
@@ -33,6 +33,7 @@ import java.util.Iterator;
import java.util.List;
import org.hibernate.HibernateException;
+import org.hibernate.annotations.common.util.StringHelper;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.Mapping;
@@ -198,15 +199,18 @@ public abstract class Constraint implements RelationalModel, Serializable {
public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) {
if ( isGenerated( dialect ) ) {
+ // Certain dialects (ex: HANA) don't support FKs as expected, but other constraints can still be created.
+ // If that's the case, hasAlterTable() will be true, but getAddForeignKeyConstraintString will return
+ // empty string. Prevent blank "alter table" statements.
String constraintString = sqlConstraintString( dialect, getName(), defaultCatalog, defaultSchema );
- StringBuilder buf = new StringBuilder( "alter table " )
- .append( getTable().getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
- .append( constraintString );
- return buf.toString();
- }
- else {
- return null;
+ if ( !StringHelper.isEmpty( constraintString ) ) {
+ StringBuilder buf = new StringBuilder( "alter table " )
+ .append( getTable().getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
+ .append( constraintString );
+ return buf.toString();
+ }
}
+ return null;
}
public List getColumns() {
diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/ASTParserLoadingTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/ASTParserLoadingTest.java
index dcb4214371..26cb5bf005 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/hql/ASTParserLoadingTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/hql/ASTParserLoadingTest.java
@@ -756,13 +756,14 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase {
else {
s.createQuery( "from Animal where lower(upper('foo') || upper(:bar)) like 'f%'" ).setString( "bar", "xyz" ).list();
}
- if ( !( getDialect() instanceof PostgreSQLDialect || getDialect() instanceof PostgreSQL81Dialect
- || getDialect() instanceof MySQLDialect || getDialect() instanceof AbstractHANADialect ) ) {
- s.createQuery( "from Animal where abs(cast(1 as float) - cast(:param as float)) = 1.0" )
+
+ if ( getDialect() instanceof AbstractHANADialect ) {
+ s.createQuery( "from Animal where abs(cast(1 as double) - cast(:param as double)) = 1.0" )
.setLong( "param", 1 ).list();
}
- else if ( getDialect() instanceof AbstractHANADialect ) {
- s.createQuery( "from Animal where abs(cast(1 as double) - cast(:param as double)) = 1.0" )
+ else if ( !( getDialect() instanceof PostgreSQLDialect || getDialect() instanceof PostgreSQL81Dialect
+ || getDialect() instanceof MySQLDialect ) ) {
+ s.createQuery( "from Animal where abs(cast(1 as float) - cast(:param as float)) = 1.0" )
.setLong( "param", 1 ).list();
}