I have a Grails application that will run against either a SQL Server or Oracle backend. I am using GORM as an ORM.
I want to map a large text field in a way that supports both database types. In my Grails domain class I have something like:
class Note {
String content
static constraints = {
content nullable: false, blank: false
}
}
I then declare database tables that look like this:
-- oracle
CREATE TABLE NOTE
(
id NUMBER(19, 0) NOT NULL,
version NUMBER(19, 0) NOT NULL,
content CLOB NOT NULL
);
-- SQL Server
CREATE TABLE NOTE
(
id NUMERIC(19, 0) NOT NULL,
version NUMERIC(19, 0) NOT NULL,
content NVARCHAR(MAX) NOT NULL
);
GORM is running in validate
mode on startup, and I can't find a combination of Oracle and SQL Server data types and GORM mappings that allow the storage or large text fields without GORM failing to start correctly.
I have tried:
setting the type to text
in mappings
, but this doesn't seem to work. Oracle complains about expecting the content
field to be of type long
, and SQL Server wants a type of text
in these circumstances.
setting the type
to clob
, which passes schema validation but then doesn't allow me to set the field as a string value - GORM expects data of type CLOB
.
How should I configure my database definitions and GORM to make this work?
As hackish as it is, a solution eventually emerged: by querying the Grails configuration at startup time, you can select an appropriate data type.
class Note {
String content
static constraints = {
content nullable: false, blank: false
}
static mappings = {
content sqlType: DbSupport.bigStringType
}
}
class DbSupport {
static def getBigStringType() {
// examine which hibernate dialect is selected, and pick
// an appropriate type mapping for that database type:
def dialect = ApplicationHolder.application.config.dataSource.dialect
switch (dialect) {
case "org.hibernate.dialect.SQLServerDialect":
return "nvarchar"
break
case "org.hibernate.dialect.Oracle10gDialect":
return "clob"
break
}
}
}