Here is a dialect for Composite Information Server. Save the following into a CompositeDialect.java file under the org.hibernate.dialect package, and then reference CompositeDialect as the dialect to use in your Hibernate configuration:
Code:
package org.hibernate.dialect;
import java.io.Serializable;
import java.sql.Types;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Hibernate;
import org.hibernate.JDBCException;
import org.hibernate.LockMode;
import org.hibernate.StaleObjectStateException;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.lock.LockingStrategy;
import org.hibernate.dialect.lock.SelectLockingStrategy;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.persister.entity.Lockable;
/**
* An SQL dialect compatible with Composite Information Server (Composite SQL).
* <p/>
* Note this version supports CIS version 4.6.0.02.83 and higher only. This
* version includes an additional query option which allows us to effectively
* achieve limit/offset functionality. This is expected to be achieved without
* the use of query options, using standard SQL syntax, in a future CIS version.
* IMPORTANT: This version portends to support sequences, but only because we
* are content to get past app initialization and gain access to read-only
* functionality (for existing apps which may have annotations for sequences).
* Further refinement is recommended for production or non read-only use.
*
*/
public class CompositeDialect extends Dialect {
private static final Log log = LogFactory.getLog( CompositeDialect.class );
public CompositeDialect() {
super();
registerColumnType( Types.BIGINT, "bigint" );
registerColumnType( Types.BINARY, "binary" );
registerColumnType( Types.BIT, "bit" );
registerColumnType( Types.CHAR, "char(1)" );
registerColumnType( Types.DATE, "date" );
registerColumnType( Types.DECIMAL, "decimal" );
registerColumnType( Types.DOUBLE, "double" );
registerColumnType( Types.FLOAT, "float" );
registerColumnType( Types.INTEGER, "integer" );
registerColumnType( Types.LONGVARBINARY, "longvarbinary" );
registerColumnType( Types.LONGVARCHAR, "longvarchar" );
registerColumnType( Types.SMALLINT, "smallint" );
registerColumnType( Types.TINYINT, "tinyint" );
registerColumnType( Types.TIME, "time" );
registerColumnType( Types.TIMESTAMP, "timestamp" );
registerColumnType( Types.VARCHAR, "varchar($l)" );
registerColumnType( Types.VARBINARY, "varbinary($l)" );
registerColumnType( Types.NUMERIC, "numeric" );
registerColumnType( Types.BLOB, "longvarbinary" );
registerColumnType( Types.CLOB, "longvarchar" );
registerFunction( "chr", new StandardSQLFunction( "chr", Hibernate.CHARACTER ) );
registerFunction( "char_length", new StandardSQLFunction( "char_length", Hibernate.LONG ) );
registerFunction( "character_length", new StandardSQLFunction( "character_length", Hibernate.LONG ) );
registerFunction( "length", new StandardSQLFunction( "length", Hibernate.LONG ) );
registerFunction( "lower", new StandardSQLFunction( "lower" ) );
registerFunction( "upper", new StandardSQLFunction( "upper" ) );
registerFunction( "trim", new StandardSQLFunction( "trim" ) );
registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) );
registerFunction( "space", new StandardSQLFunction( "space", Hibernate.STRING ) );
registerFunction( "current_date", new NoArgSQLFunction( "current_date", Hibernate.DATE, false ) );
registerFunction( "current_timestamp", new NoArgSQLFunction( "current_timestamp", Hibernate.TIMESTAMP, false ) );
registerFunction( "current_time", new NoArgSQLFunction( "current_time", Hibernate.TIME, false ) );
registerFunction( "day", new StandardSQLFunction( "day", Hibernate.INTEGER ) );
registerFunction( "month", new StandardSQLFunction( "month", Hibernate.INTEGER ) );
registerFunction( "year", new StandardSQLFunction( "year", Hibernate.INTEGER ) );
registerFunction( "abs", new StandardSQLFunction( "abs" ) );
registerFunction( "acos", new StandardSQLFunction( "acos", Hibernate.DOUBLE ) );
registerFunction( "asin", new StandardSQLFunction( "asin", Hibernate.DOUBLE ) );
registerFunction( "atan", new StandardSQLFunction( "atan", Hibernate.DOUBLE ) );
registerFunction( "cos", new StandardSQLFunction( "cos", Hibernate.DOUBLE ) );
registerFunction( "cot", new StandardSQLFunction( "cot", Hibernate.DOUBLE ) );
registerFunction( "exp", new StandardSQLFunction( "exp", Hibernate.DOUBLE ) );
registerFunction( "sin", new StandardSQLFunction( "sin", Hibernate.DOUBLE ) );
registerFunction( "sqrt", new StandardSQLFunction( "sqrt", Hibernate.DOUBLE ) );
registerFunction( "tan", new StandardSQLFunction( "tan", Hibernate.DOUBLE ) );
registerFunction( "pi", new NoArgSQLFunction( "pi", Hibernate.DOUBLE ) );
registerFunction( "radians", new StandardSQLFunction( "radians", Hibernate.DOUBLE ) );
registerFunction( "degrees", new StandardSQLFunction( "degrees", Hibernate.DOUBLE ) );
registerFunction( "ceiling", new StandardSQLFunction( "ceiling" ) );
registerFunction( "floor", new StandardSQLFunction( "floor" ) );
// function templates
registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) );
getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
}
/*
* START sequence-related methods.
*
* NOTE: We are read only, so there is not need for this to work!
* We are implementing these strictly for compatibility.
*/
//TODO: Will need to revisit this if this functionality is needed in the future.
public boolean supportsSequences() {
return true;
}
public String getSequenceNextValString(String sequenceName) {
return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual";
}
public String getSelectSequenceNextValString(String sequenceName) {
return sequenceName + ".nextval";
}
public String getCreateSequenceString(String sequenceName) {
return "create sequence " + sequenceName; //starts with 1, implicitly
}
public String getDropSequenceString(String sequenceName) {
return "drop sequence " + sequenceName;
}
public String getQuerySequencesString() {
return "select sequence_name from user_sequences";
}
/*
* END sequence-related methods
*/
/*
* START limit customization
*/
public boolean supportsLimit() {
return true;
}
public boolean supportsLimitOffset() {
return true;
}
public boolean supportsVariableLimit() {
return false;
}
// public boolean bindLimitParametersInReverseOrder() {
// return true;
// }
// public boolean bindLimitParametersFirst() {
// return false;
// }
/**
* Using query options to achieve limit...offset functionality. Eventually,
* this will be supported directly within the sql syntax ala SQL 2008.
* For now, max_rows_limit is the last row and rows_offset is the first row
* you want returned.
*/
public String getLimitString(String query, int offset, int limit) {
StringBuffer newSQL = new StringBuffer();
newSQL.append(query.toLowerCase().replaceFirst(
"select ", "select {OPTION MAX_ROWS_LIMIT=" + (limit + offset) + ", ROWS_OFFSET=" + (offset + 1) + "} "))
.toString();
return newSQL.toString();
}
// public String getLimitString(String sql, boolean hasOffset) {
// StringBuffer newSQL = new StringBuffer();
// if (hasOffset) {
// } else {
// }
// return newSQL.toString();
// }
/*
* END limit customization
*/
public boolean supportsUnionAll() {
return true;
}
public boolean supportsIdentityColumns() {
return true;
}
/*
* Composite doesn't support any type of DDL as of v4.6.
*/
public boolean hasAlterTable() {
return false;
}
public String getIdentityColumnString() {
return "generated by default as identity (start with 1)"; //not null is implicit
}
public String getIdentitySelectString() {
return "call identity()";
}
public String getIdentityInsertString() {
return "null";
}
public String getForUpdateString() {
return "";
}
public boolean supportsUnique() {
return false;
}
public boolean supportsColumnCheck() {
return false;
}
public boolean supportsTemporaryTables() {
return false;
}
public boolean supportsCurrentTimestampSelection() {
return false;
}
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
return new ReadUncommittedLockingStrategy( lockable, lockMode );
}
public static class ReadUncommittedLockingStrategy extends SelectLockingStrategy {
public ReadUncommittedLockingStrategy(Lockable lockable, LockMode lockMode) {
super( lockable, lockMode );
}
public void lock(Serializable id, Object version, Object object, SessionImplementor session)
throws StaleObjectStateException, JDBCException {
if ( getLockMode().greaterThan( LockMode.READ ) ) {
log.warn( "Composite supports only READ_UNCOMMITTED isolation" );
}
super.lock( id, version, object, session );
}
}
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public boolean supportsEmptyInList() {
return false;
}
public boolean supportsLobValueChangePropogation() {
return false;
}
}