From e4fb65a7235fdfbcf1dd5ddb98dbcbba6b7f1995 Mon Sep 17 00:00:00 2001 From: Burt Beckwith Date: Fri, 19 Dec 2014 23:27:49 -0500 Subject: [PATCH 1/3] unused --- scripts/_Install.groovy | 10 ---------- scripts/_Uninstall.groovy | 5 ----- scripts/_Upgrade.groovy | 10 ---------- 3 files changed, 25 deletions(-) delete mode 100644 scripts/_Install.groovy delete mode 100644 scripts/_Uninstall.groovy delete mode 100644 scripts/_Upgrade.groovy diff --git a/scripts/_Install.groovy b/scripts/_Install.groovy deleted file mode 100644 index a212160..0000000 --- a/scripts/_Install.groovy +++ /dev/null @@ -1,10 +0,0 @@ -// -// This script is executed by Grails after plugin was installed to project. -// This script is a Gant script so you can use all special variables provided -// by Gant (such as 'baseDir' which points on project base dir). You can -// use 'ant' to access a global instance of AntBuilder -// -// For example you can create directory under project tree: -// -// ant.mkdir(dir:"${basedir}/grails-app/jobs") -// diff --git a/scripts/_Uninstall.groovy b/scripts/_Uninstall.groovy deleted file mode 100644 index 7c53169..0000000 --- a/scripts/_Uninstall.groovy +++ /dev/null @@ -1,5 +0,0 @@ -// -// This script is executed by Grails when the plugin is uninstalled from project. -// Use this script if you intend to do any additional clean-up on uninstall, but -// beware of messing up SVN directories! -// diff --git a/scripts/_Upgrade.groovy b/scripts/_Upgrade.groovy deleted file mode 100644 index 6a1a4c9..0000000 --- a/scripts/_Upgrade.groovy +++ /dev/null @@ -1,10 +0,0 @@ -// -// This script is executed by Grails during application upgrade ('grails upgrade' -// command). This script is a Gant script so you can use all special variables -// provided by Gant (such as 'baseDir' which points on project base dir). You can -// use 'ant' to access a global instance of AntBuilder -// -// For example you can create directory under project tree: -// -// ant.mkdir(dir:"${basedir}/grails-app/jobs") -// From 3f2f1a2ba307ed41dca3df4746ccbfbb988e585d Mon Sep 17 00:00:00 2001 From: Burt Beckwith Date: Fri, 19 Dec 2014 23:28:58 -0500 Subject: [PATCH 2/3] cleanup --- .gitignore | 24 +++---- PostgresqlExtensionsGrailsPlugin.groovy | 26 ++------ application.properties | 4 +- grails-app/conf/BuildConfig.groovy | 42 ++++-------- grails-app/conf/Config.groovy | 17 ++--- grails-app/conf/DataSource.groovy | 47 ++++---------- .../domain/test/criteria/array/User.groovy | 6 +- .../array/PgArrayTestSearchService.groovy | 4 +- .../hstore/PgHstoreTestSearchService.groovy | 2 +- .../json/PgJsonTestSearchService.groovy | 2 +- scripts/_Events.groovy | 15 +++-- .../postgresql/criteria/ArrayCriterias.groovy | 14 ++-- .../criteria/HstoreCriterias.groovy | 10 +-- .../postgresql/criteria/JsonCriterias.groovy | 6 +- .../hstore/HstoreASTTransformation.groovy | 15 +++-- .../postgresql/hstore/HstoreDomainType.groovy | 8 +-- .../PostgresqlExtensionsDialect.java | 3 +- .../criterion/array/PgArrayExpression.java | 3 +- .../hstore/PgHstoreOperatorExpression.java | 2 - .../hstore/PgHstoreValueFunction.java | 2 - .../criterion/json/PgJsonExpression.java | 2 - .../hibernate/usertype/ArrayType.java | 64 +++++++------------ .../hibernate/usertype/BidiEnumMap.java | 3 +- .../hibernate/usertype/HstoreHelper.java | 18 +++--- .../usertype/HstoreParseException.java | 4 +- .../hibernate/usertype/HstoreParser.java | 45 ++++++------- .../hibernate/usertype/JsonMapType.java | 30 +++------ .../hibernate/utils/PgArrayUtils.java | 60 ++++++++--------- 28 files changed, 188 insertions(+), 290 deletions(-) diff --git a/.gitignore b/.gitignore index ee32444..e97c4b5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,22 @@ -.project -.classpath -.settings +/.project +/.classpath +/.settings *sublime* cobertura.ser -target* +/target plugin.xml -grails-app/views -grails-app/controllers -grails-app/conf/UrlMappings.groovy -web-app/* +/grails-app/controllers +/grails-app/conf/UrlMappings.groovy +/grails-app/views +/web-app grails-postgresql-extensions-*.zip -.idea/ +grails-postgresql-extensions-*.zip.sha1 +/.idea *.iml *.swp *.ids *.ipr *.iws -out/ -projectFilesBackup/ +/out +/projectFilesBackup +*.log diff --git a/PostgresqlExtensionsGrailsPlugin.groovy b/PostgresqlExtensionsGrailsPlugin.groovy index 5d20930..fb53971 100644 --- a/PostgresqlExtensionsGrailsPlugin.groovy +++ b/PostgresqlExtensionsGrailsPlugin.groovy @@ -1,17 +1,12 @@ import net.kaleidos.hibernate.postgresql.criteria.ArrayCriterias import net.kaleidos.hibernate.postgresql.criteria.HstoreCriterias import net.kaleidos.hibernate.postgresql.criteria.JsonCriterias +import net.kaleidos.hibernate.postgresql.hstore.HstoreDomainType class PostgresqlExtensionsGrailsPlugin { - // the plugin version def version = "4.3.0" - // the version or versions of Grails the plugin is designed for def grailsVersion = "2.0 > *" - // the other plugins this plugin depends on - def dependsOn = [:] - // resources that are excluded from plugin packaging def pluginExcludes = [ - "grails-app/views/error.gsp", "grails-app/controllers/**", "grails-app/domain/**", "grails-app/i18n/**", @@ -26,34 +21,21 @@ class PostgresqlExtensionsGrailsPlugin { def author = "Iván López" def authorEmail = "lopez.ivan@gmail.com" def description = '''\ -This plugin provides hibernate user types to support for Postgresql Native Types like Array, HStore, JSON,... as well as new criterias to query this native types +Provides Hibernate user types to support for Postgresql Native Types like Array, HStore, JSON,... as well as new criterias to query this native types ''' - // URL to the plugin's documentation def documentation = "https://github.com/kaleidos/grails-postgresql-extensions/blob/master/README.md" - - // Extra (optional) plugin metadata - - // License: one of 'APACHE', 'GPL2', 'GPL3' def license = "APACHE" - - // Details of company behind the plugin (if there is one) def organization = [ name: "Kaleidos", url: "http://kaleidos.net" ] - - // Any additional developers beyond the author specified above. def developers = [ [ name: "Alonso Torres", email: "alonso.javier.torres@gmail.com" ]] - - // Location of the plugin's issue tracker. def issueManagement = [ system: "GITHUB", url: "https://github.com/kaleidos/grails-postgresql-extensions/issues" ] - - // Online location of the plugin's browseable source code. def scm = [ url: "https://github.com/kaleidos/grails-postgresql-extensions" ] // TODO: Extract to utils class or service private decorateConstructor(className, metaclass) { def hstoreProperties = [] metaclass.properties.each { prop-> - if (prop.type == net.kaleidos.hibernate.postgresql.hstore.HstoreDomainType) { + if (prop.type == HstoreDomainType) { println "[PostgresqlExtensions] Adding property ${className}.${prop.name} as a hstore property" hstoreProperties << prop.name } @@ -63,7 +45,7 @@ This plugin provides hibernate user types to support for Postgresql Native Types def constructor = metaclass.retrieveConstructor(Map) metaclass.constructor = { Map m -> hstoreProperties.each { name-> - m[name] = new net.kaleidos.hibernate.postgresql.hstore.HstoreDomainType(m[name]) + m[name] = new HstoreDomainType(m[name]) } return constructor.newInstance(m) } diff --git a/application.properties b/application.properties index 8afbf7c..66b122d 100644 --- a/application.properties +++ b/application.properties @@ -1,4 +1,2 @@ -#Grails Metadata file -#Fri Jul 18 09:55:35 CEST 2014 app.grails.version=2.4.2 -app.name=grails-postgresql-extensions \ No newline at end of file +app.name=grails-postgresql-extensions diff --git a/grails-app/conf/BuildConfig.groovy b/grails-app/conf/BuildConfig.groovy index ae87eba..52adddd 100644 --- a/grails-app/conf/BuildConfig.groovy +++ b/grails-app/conf/BuildConfig.groovy @@ -1,42 +1,23 @@ grails.project.work.dir = "target/work" -grails.project.fork = [ - // configure settings for compilation JVM, note that if you alter the Groovy version forked compilation is required - // compile: [maxMemory: 256, minMemory: 64, debug: false, maxPerm: 256, daemon:true], +grails.project.dependency.resolver = 'maven' +grails.project.dependency.resolution = { - // configure settings for the test-app JVM, uses the daemon by default - // test : [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, daemon: true], - // configure settings for the run-app JVM - run : [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, forkReserve: false], - // configure settings for the run-war JVM - war : [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, forkReserve: false], - // configure settings for the Console UI JVM - console: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256] -] + inherits 'global' + log 'warn' + legacyResolve true -grails.project.dependency.resolver = "maven" // or ivy -grails.project.dependency.resolution = { - // inherit Grails' default dependencies - inherits("global") { - // uncomment to disable ehcache - // excludes 'ehcache' - } - log "warn" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose' - legacyResolve true // whether to do a secondary resolve on plugin installation, not advised but set here for backwards compatibility repositories { grailsCentral() + mavenLocal() mavenCentral() } + dependencies { - // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg. runtime 'org.postgresql:postgresql:9.2-1004-jdbc4', { export = false } - test "org.springframework:spring-orm:$springVersion" - test "org.springframework:spring-expression:$springVersion" - test "org.springframework:spring-aop:$springVersion" - compile 'com.google.code.gson:gson:2.2.4' // Coveralls plugin @@ -46,10 +27,11 @@ grails.project.dependency.resolution = { } plugins { - build ":tomcat:7.0.53", - ":release:3.0.1", - ":rest-client-builder:1.0.3", - ":coveralls:0.1.3", { + build ':release:3.0.1', ':rest-client-builder:2.0.3', { + export = false + } + + build ":coveralls:0.1.3", { export = false } diff --git a/grails-app/conf/Config.groovy b/grails-app/conf/Config.groovy index 81cedce..2f1168d 100644 --- a/grails-app/conf/Config.groovy +++ b/grails-app/conf/Config.groovy @@ -1,15 +1,6 @@ log4j = { - error 'org.codehaus.groovy.grails.web.servlet', // controllers - 'org.codehaus.groovy.grails.web.pages', // GSP - 'org.codehaus.groovy.grails.web.sitemesh', // layouts - 'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping - 'org.codehaus.groovy.grails.web.mapping', // URL mapping - 'org.codehaus.groovy.grails.commons', // core / classloading - 'org.codehaus.groovy.grails.plugins', // plugins - 'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration - 'org.springframework', - 'org.hibernate', - 'net.sf.ehcache.hibernate' - - warn 'org.mortbay.log' + error 'org.codehaus.groovy.grails', + 'org.springframework', + 'org.hibernate', + 'net.sf.ehcache.hibernate' } diff --git a/grails-app/conf/DataSource.groovy b/grails-app/conf/DataSource.groovy index 136ce70..3f99929 100644 --- a/grails-app/conf/DataSource.groovy +++ b/grails-app/conf/DataSource.groovy @@ -1,53 +1,30 @@ dataSource { pooled = true - driverClassName = "org.h2.Driver" - username = "sa" - password = "" + dbCreate = 'none' + dialect = 'net.kaleidos.hibernate.PostgresqlExtensionsDialect' + driverClassName = 'org.postgresql.Driver' + username = 'pg_extensions' + password = 'pg_extensions' } + hibernate { cache.use_second_level_cache = true cache.use_query_cache = false cache.region.factory_class = 'org.hibernate.cache.ehcache.EhCacheRegionFactory' } -// environment specific settings + environments { development { dataSource { - dbCreate = "" // one of '', 'create', 'create-drop','update' - driverClassName = "org.postgresql.Driver" - dialect = "net.kaleidos.hibernate.PostgresqlExtensionsDialect" - url = "jdbc:postgresql://localhost:5432/pg_extensions" - username = "pg_extensions" - password = "pg_extensions" - loggingSql = true + url = 'jdbc:postgresql://localhost/pg_extensions' + logSql = true } } test { dataSource { - dbCreate = "create-drop" // one of '', 'create', 'create-drop','update' - driverClassName = "org.postgresql.Driver" - dialect = "net.kaleidos.hibernate.PostgresqlExtensionsDialect" - url = "jdbc:postgresql://localhost:5432/pg_extensions_test" - username = "pg_extensions" - password = "pg_extensions" - loggingSql = false - } - } - production { - dataSource { - dbCreate = "update" - url = "jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000" - pooled = true - properties { - maxActive = -1 - minEvictableIdleTimeMillis=1800000 - timeBetweenEvictionRunsMillis=1800000 - numTestsPerEvictionRun=3 - testOnBorrow=true - testWhileIdle=true - testOnReturn=true - validationQuery="SELECT 1" - } + dbCreate = 'create-drop' + url = 'jdbc:postgresql://localhost/pg_extensions_test' + logSql = false } } } diff --git a/grails-app/domain/test/criteria/array/User.groovy b/grails-app/domain/test/criteria/array/User.groovy index 9290e48..1d2fb17 100644 --- a/grails-app/domain/test/criteria/array/User.groovy +++ b/grails-app/domain/test/criteria/array/User.groovy @@ -9,7 +9,5 @@ class User { table "pg_extensions_user" } - public String toString() { - return name - } -} \ No newline at end of file + String toString() { name } +} diff --git a/grails-app/services/test/criteria/array/PgArrayTestSearchService.groovy b/grails-app/services/test/criteria/array/PgArrayTestSearchService.groovy index 9133f1d..e850fe5 100644 --- a/grails-app/services/test/criteria/array/PgArrayTestSearchService.groovy +++ b/grails-app/services/test/criteria/array/PgArrayTestSearchService.groovy @@ -4,7 +4,7 @@ class PgArrayTestSearchService { static transactional = false - List search(String field, String criteriaName, Object value) { + List search(String field, String criteriaName, value) { Like.withCriteria { "${criteriaName}" field, value } @@ -16,7 +16,7 @@ class PgArrayTestSearchService { } } - List searchWithJoin(String field, String criteriaName, Object value) { + List searchWithJoin(String field, String criteriaName, value) { User.withCriteria { like { "${criteriaName}" field, value diff --git a/grails-app/services/test/criteria/hstore/PgHstoreTestSearchService.groovy b/grails-app/services/test/criteria/hstore/PgHstoreTestSearchService.groovy index 4683bdc..2aa3117 100644 --- a/grails-app/services/test/criteria/hstore/PgHstoreTestSearchService.groovy +++ b/grails-app/services/test/criteria/hstore/PgHstoreTestSearchService.groovy @@ -5,7 +5,7 @@ import test.hstore.TestHstore class PgHstoreTestSearchService { static transactional = false - List search(String field, String criteriaName, Object value) { + List search(String field, String criteriaName, value) { TestHstore.withCriteria { "${criteriaName}" field, value } diff --git a/grails-app/services/test/criteria/json/PgJsonTestSearchService.groovy b/grails-app/services/test/criteria/json/PgJsonTestSearchService.groovy index f29bbef..ed9eb28 100644 --- a/grails-app/services/test/criteria/json/PgJsonTestSearchService.groovy +++ b/grails-app/services/test/criteria/json/PgJsonTestSearchService.groovy @@ -5,7 +5,7 @@ import test.json.TestMapJson class PgJsonTestSearchService { static transactional = false - List search(String criteriaName, String field, String jsonAttribute, Object value) { + List search(String criteriaName, String field, String jsonAttribute, value) { TestMapJson.withCriteria { "${criteriaName}" field, jsonAttribute, value } diff --git a/scripts/_Events.groovy b/scripts/_Events.groovy index 43bf160..ce32c28 100644 --- a/scripts/_Events.groovy +++ b/scripts/_Events.groovy @@ -2,19 +2,24 @@ eventCompileStart = { target -> compileAST(postgresqlExtensionsPluginDir, classesDirPath) } -def compileAST(def srcBaseDir, def destDir) { +void compileAST(srcBaseDir, destDir) { ant.sequential { eventListener.triggerEvent("StatusUpdate", "Precompiling AST Transformations...") - eventListener.triggerEvent("StatusUpdate", "src ${srcBaseDir} ${destDir}") - path id: "grails.compile.classpath", compileClasspath - def classpathId = "grails.compile.classpath" + eventListener.triggerEvent("StatusUpdate", "src $srcBaseDir $destDir") + + String classpathId = "grails.compile.classpath" + + path id: classpathId, compileClasspath + mkdir dir: destDir - groovyc(destdir: destDir, + groovyc( + destdir: destDir, srcDir: "$srcBaseDir/src/groovy/net/kaleidos/hibernate/postgresql/hstore", classpathref: classpathId, verbose: grailsSettings.verboseCompile, stacktrace: "yes", encoding: "UTF-8") + eventListener.triggerEvent("Done precompiling AST Transformations!") } } diff --git a/src/groovy/net/kaleidos/hibernate/postgresql/criteria/ArrayCriterias.groovy b/src/groovy/net/kaleidos/hibernate/postgresql/criteria/ArrayCriterias.groovy index e8de1a9..9639ff3 100644 --- a/src/groovy/net/kaleidos/hibernate/postgresql/criteria/ArrayCriterias.groovy +++ b/src/groovy/net/kaleidos/hibernate/postgresql/criteria/ArrayCriterias.groovy @@ -6,7 +6,7 @@ import net.kaleidos.hibernate.criterion.array.PgEmptinessExpression class ArrayCriterias { - public ArrayCriterias() { + ArrayCriterias() { addContainsOperator() addIsContainedByOperator() addOverlapsOperator() @@ -24,7 +24,7 @@ class ArrayCriterias { * @param propertyValue The property value * @return A Criterion instance */ - HibernateCriteriaBuilder.metaClass.pgArrayContains = { String propertyName, Object propertyValue -> + HibernateCriteriaBuilder.metaClass.pgArrayContains = { String propertyName, propertyValue -> if (!validateSimpleExpression()) { throwRuntimeException(new IllegalArgumentException("Call to [pgArrayContains] with propertyName [" + propertyName + "] and value [" + propertyValue + "] not allowed here.")) @@ -44,7 +44,7 @@ class ArrayCriterias { * @param propertyValue The property value * @return A Criterion instance */ - HibernateCriteriaBuilder.metaClass.pgArrayIsContainedBy = { String propertyName, Object propertyValue -> + HibernateCriteriaBuilder.metaClass.pgArrayIsContainedBy = { String propertyName, propertyValue -> if (!validateSimpleExpression()) { throwRuntimeException(new IllegalArgumentException("Call to [pgArrayIsContainedBy] with propertyName [" + propertyName + "] and value [" + propertyValue + "] not allowed here.")) @@ -64,7 +64,7 @@ class ArrayCriterias { * @param propertyValue The property value * @return A Criterion instance */ - HibernateCriteriaBuilder.metaClass.pgArrayOverlaps = { String propertyName, Object propertyValue -> + HibernateCriteriaBuilder.metaClass.pgArrayOverlaps = { String propertyName, propertyValue -> if (!validateSimpleExpression()) { throwRuntimeException(new IllegalArgumentException("Call to [pgOverlap] with propertyName [" + propertyName + "] and value [" + propertyValue + "] not allowed here.")) @@ -123,7 +123,7 @@ class ArrayCriterias { * @param propertyValue The property value * @return A Criterion instance */ - HibernateCriteriaBuilder.metaClass.pgArrayIsEmptyOrContains = { String propertyName, Object propertyValue -> + HibernateCriteriaBuilder.metaClass.pgArrayIsEmptyOrContains = { String propertyName, propertyValue -> if (!validateSimpleExpression()) { throwRuntimeException(new IllegalArgumentException("Call to [pgArrayIsEmptyOrContains] with propertyName [" + propertyName + "] and value [" + propertyValue + "] not allowed here.")) @@ -147,7 +147,7 @@ class ArrayCriterias { * @param propertyValue The property value * @return A Criterion instance */ - HibernateCriteriaBuilder.metaClass.pgArrayEquals = { String propertyName, Object propertyValue -> + HibernateCriteriaBuilder.metaClass.pgArrayEquals = { String propertyName, propertyValue -> if (!validateSimpleExpression()) { throwRuntimeException(new IllegalArgumentException("Call to [pgArrayEquals] with propertyName [" + propertyName + "] and value [" + propertyValue + "] not allowed here.")) @@ -167,7 +167,7 @@ class ArrayCriterias { * @param propertyValue The property value * @return A Criterion instance */ - HibernateCriteriaBuilder.metaClass.pgArrayNotEquals = { String propertyName, Object propertyValue -> + HibernateCriteriaBuilder.metaClass.pgArrayNotEquals = { String propertyName, propertyValue -> if (!validateSimpleExpression()) { throwRuntimeException(new IllegalArgumentException("Call to [pgArrayNotEquals] with propertyName [" + propertyName + "] and value [" + propertyValue + "] not allowed here.")) diff --git a/src/groovy/net/kaleidos/hibernate/postgresql/criteria/HstoreCriterias.groovy b/src/groovy/net/kaleidos/hibernate/postgresql/criteria/HstoreCriterias.groovy index e692531..6f42040 100644 --- a/src/groovy/net/kaleidos/hibernate/postgresql/criteria/HstoreCriterias.groovy +++ b/src/groovy/net/kaleidos/hibernate/postgresql/criteria/HstoreCriterias.groovy @@ -5,14 +5,14 @@ import net.kaleidos.hibernate.criterion.hstore.PgHstoreValueFunction import net.kaleidos.hibernate.criterion.hstore.PgHstoreOperatorExpression class HstoreCriterias { - public HstoreCriterias() { + HstoreCriterias() { addPgHstoreContainsKey() addPgHstoreContains() addPgHstoreIsContained() } - public void addPgHstoreContainsKey() { - HibernateCriteriaBuilder.metaClass.pgHstoreContainsKey = { String propertyName, Object propertyValue -> + void addPgHstoreContainsKey() { + HibernateCriteriaBuilder.metaClass.pgHstoreContainsKey = { String propertyName, propertyValue -> if (!validateSimpleExpression()) { throwRuntimeException(new IllegalArgumentException("Call to [pgHstoreContains] with propertyName [" + propertyName + "] and value [" + propertyValue + "] not allowed here.")) @@ -23,7 +23,7 @@ class HstoreCriterias { return addToCriteria(new PgHstoreValueFunction(propertyName, propertyValue, "exist")) } } - public void addPgHstoreContains() { + void addPgHstoreContains() { HibernateCriteriaBuilder.metaClass.pgHstoreContains = { String propertyName, Map values -> if (!validateSimpleExpression()) { throwRuntimeException(new IllegalArgumentException("Call to [pgHstoreContains] with propertyName [" + @@ -34,7 +34,7 @@ class HstoreCriterias { } } - public void addPgHstoreIsContained() { + void addPgHstoreIsContained() { HibernateCriteriaBuilder.metaClass.pgHstoreIsContained = { String propertyName, Map values -> if (!validateSimpleExpression()) { throwRuntimeException(new IllegalArgumentException("Call to [pgHstoreIsContained] with propertyName [" + diff --git a/src/groovy/net/kaleidos/hibernate/postgresql/criteria/JsonCriterias.groovy b/src/groovy/net/kaleidos/hibernate/postgresql/criteria/JsonCriterias.groovy index 44845a6..9122c4a 100644 --- a/src/groovy/net/kaleidos/hibernate/postgresql/criteria/JsonCriterias.groovy +++ b/src/groovy/net/kaleidos/hibernate/postgresql/criteria/JsonCriterias.groovy @@ -5,7 +5,7 @@ import net.kaleidos.hibernate.criterion.json.PgJsonExpression class JsonCriterias { - public JsonCriterias() { + JsonCriterias() { addHasFieldValueOperator() } @@ -17,7 +17,7 @@ class JsonCriterias { * @param propertyValue The property value * @return A Criterion instance */ - HibernateCriteriaBuilder.metaClass.pgJsonHasFieldValue = { String propertyName, String jsonAttribute, Object propertyValue -> + HibernateCriteriaBuilder.metaClass.pgJsonHasFieldValue = { String propertyName, String jsonAttribute, propertyValue -> if (!validateSimpleExpression()) { throwRuntimeException(new IllegalArgumentException("Call to [pgJsonHasFieldValue] with propertyName [" + propertyName + "], jsonAttribute [" + jsonAttribute + "] and value [" + propertyValue + "] not allowed here.")) @@ -29,4 +29,4 @@ class JsonCriterias { return addToCriteria(new PgJsonExpression(propertyName, jsonAttribute, propertyValue, "=")) } } -} \ No newline at end of file +} diff --git a/src/groovy/net/kaleidos/hibernate/postgresql/hstore/HstoreASTTransformation.groovy b/src/groovy/net/kaleidos/hibernate/postgresql/hstore/HstoreASTTransformation.groovy index 309710c..bff5fe3 100644 --- a/src/groovy/net/kaleidos/hibernate/postgresql/hstore/HstoreASTTransformation.groovy +++ b/src/groovy/net/kaleidos/hibernate/postgresql/hstore/HstoreASTTransformation.groovy @@ -11,20 +11,21 @@ import org.codehaus.groovy.transform.AbstractASTTransformation import org.codehaus.groovy.transform.GroovyASTTransformation @GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION) -public class HstoreASTTransformation extends AbstractASTTransformation { +class HstoreASTTransformation extends AbstractASTTransformation { - public void visit(ASTNode[] nodes, SourceUnit sourceUnit) { + void visit(ASTNode[] nodes, SourceUnit sourceUnit) { if (!nodes) return if (!nodes[0] || !nodes[1]) return if (!(nodes[0] instanceof AnnotationNode)) return FieldNode field = nodes[1] - if (field.originType.typeClass.name != java.util.Map.class.name) { - sourceUnit.addError(new SyntaxException("It is only possible to annotate Map fields with @Hstore annotation", nodes[0].lineNumber + 1, nodes[0].columnNumber)) + if (field.originType.typeClass.name != Map.name) { + sourceUnit.addError(new SyntaxException("It is only possible to annotate Map fields with @Hstore annotation", + nodes[0].lineNumber + 1, nodes[0].columnNumber)) } else { ClassNode classOwner = field.owner - println "[PostgresqlExtensions] Converting ${classOwner}.${field.name} to Hstore type" - field.type = new ClassNode(net.kaleidos.hibernate.postgresql.hstore.HstoreDomainType) + println "[PostgresqlExtensions] Converting ${classOwner}.${field.name} to Hstore type" + field.type = new ClassNode(HstoreDomainType) } } -} \ No newline at end of file +} diff --git a/src/groovy/net/kaleidos/hibernate/postgresql/hstore/HstoreDomainType.groovy b/src/groovy/net/kaleidos/hibernate/postgresql/hstore/HstoreDomainType.groovy index 8a709d4..bdad8ea 100644 --- a/src/groovy/net/kaleidos/hibernate/postgresql/hstore/HstoreDomainType.groovy +++ b/src/groovy/net/kaleidos/hibernate/postgresql/hstore/HstoreDomainType.groovy @@ -3,8 +3,8 @@ package net.kaleidos.hibernate.postgresql.hstore class HstoreDomainType { Map dataStore - public HstoreDomainType(Map data) { - this.dataStore = data + HstoreDomainType(Map data) { + dataStore = data } def methodMissing(String name, args) { @@ -20,7 +20,7 @@ class HstoreDomainType { this.@dataStore[name] = value } - public String toString() { - this.dataStore.toString() + String toString() { + dataStore.toString() } } diff --git a/src/java/net/kaleidos/hibernate/PostgresqlExtensionsDialect.java b/src/java/net/kaleidos/hibernate/PostgresqlExtensionsDialect.java index bf6ae89..71287b8 100644 --- a/src/java/net/kaleidos/hibernate/PostgresqlExtensionsDialect.java +++ b/src/java/net/kaleidos/hibernate/PostgresqlExtensionsDialect.java @@ -19,7 +19,6 @@ public class PostgresqlExtensionsDialect extends PostgreSQL81Dialect { * Register postgresql types */ public PostgresqlExtensionsDialect() { - super(); registerColumnType(Types.ARRAY, "array"); registerColumnType(ArrayType.LONG_ARRAY, "int8[]"); registerColumnType(ArrayType.INTEGER_ARRAY, "int[]"); @@ -72,4 +71,4 @@ public void configure(final Type type, final Properties params, final Dialect di super.configure(type, params, dialect); } } -} \ No newline at end of file +} diff --git a/src/java/net/kaleidos/hibernate/criterion/array/PgArrayExpression.java b/src/java/net/kaleidos/hibernate/criterion/array/PgArrayExpression.java index 4ad8ea8..c595aba 100644 --- a/src/java/net/kaleidos/hibernate/criterion/array/PgArrayExpression.java +++ b/src/java/net/kaleidos/hibernate/criterion/array/PgArrayExpression.java @@ -28,7 +28,6 @@ protected PgArrayExpression(String propertyName, Object value, String op) { this.op = op; } - @Override public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { ArrayType arrayType = checkAndGetArrayType(criteria, criteriaQuery); @@ -40,7 +39,6 @@ public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws ); } - @Override public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { ArrayType arrayType = checkAndGetArrayType(criteria, criteriaQuery); @@ -50,6 +48,7 @@ public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuer value, Integer.class, new PgArrayUtils.MapFunction() { + @Override @SuppressWarnings("rawtypes") public Object map(Object o) { try { diff --git a/src/java/net/kaleidos/hibernate/criterion/hstore/PgHstoreOperatorExpression.java b/src/java/net/kaleidos/hibernate/criterion/hstore/PgHstoreOperatorExpression.java index 2c3f50f..32a8c59 100644 --- a/src/java/net/kaleidos/hibernate/criterion/hstore/PgHstoreOperatorExpression.java +++ b/src/java/net/kaleidos/hibernate/criterion/hstore/PgHstoreOperatorExpression.java @@ -28,7 +28,6 @@ protected PgHstoreOperatorExpression(String propertyName, Map val this.operator = operator; } - @Override public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { String[] columns = StringHelper.suffix(criteriaQuery.findColumns(propertyName, criteria), ""); for (int i=0; i CLASS_TO_SQL_CODE = new HashMap(); + static { + CLASS_TO_SQL_CODE.put(Integer.class, INTEGER_ARRAY); + CLASS_TO_SQL_CODE.put(Long.class, LONG_ARRAY); + CLASS_TO_SQL_CODE.put(String.class, STRING_ARRAY); + CLASS_TO_SQL_CODE.put(Float.class, FLOAT_ARRAY); + CLASS_TO_SQL_CODE.put(Double.class, DOUBLE_ARRAY); + } + private Class typeClass; private BidiEnumMap bidiMap; - @Override public Object assemble(Serializable cached, Object owner) throws HibernateException { return cached; } - @Override public Serializable disassemble(Object value) throws HibernateException { return (Serializable) value; } - @Override public boolean equals(Object x, Object y) throws HibernateException { return x == null ? y == null : x.equals(y); } - @Override public int hashCode(Object value) throws HibernateException { return value == null ? 0 : value.hashCode(); } - @Override public boolean isMutable() { return true; } - @Override public Object deepCopy(Object value) throws HibernateException { return value; } - @Override public Object replace(Object original, Object target, Object owner) throws HibernateException { return original; } - @Override public void setParameterValues(Properties parameters) { - this.typeClass = (Class) parameters.get("type"); + typeClass = (Class) parameters.get("type"); if (typeClass == null) { throw new RuntimeException("The user type needs to be configured with the type. None provided"); } } - @Override public Class returnedClass() { - return java.lang.reflect.Array.newInstance(this.typeClass, 0).getClass(); + return java.lang.reflect.Array.newInstance(typeClass, 0).getClass(); } - @Override public int[] sqlTypes() { - if (Integer.class.equals(this.typeClass)) { - return new int[]{INTEGER_ARRAY}; - } - - if (Long.class.equals(this.typeClass)) { - return new int[]{LONG_ARRAY}; - } - if (String.class.equals(this.typeClass)) { - return new int[]{STRING_ARRAY}; + Integer type = CLASS_TO_SQL_CODE.get(typeClass); + if (type != null) { + return new int[] { type }; } - if (Float.class.equals(this.typeClass)) { - return new int[]{FLOAT_ARRAY}; - } - - if (Double.class.equals(this.typeClass)) { - return new int[]{DOUBLE_ARRAY}; - } - - if (this.typeClass.isEnum()) { + if (typeClass.isEnum()) { return new int[]{ENUM_INTEGER_ARRAY}; } - throw new RuntimeException("The type " + this.typeClass + " is not a valid type"); + throw new RuntimeException("The type " + typeClass + " is not a valid type"); } - @Override public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException { Object[] result = null; Class typeArrayClass = java.lang.reflect.Array.newInstance(typeClass, 0).getClass(); - Array array = rs.getArray(names[0]); + java.sql.Array array = rs.getArray(names[0]); if (!rs.wasNull()) { if (typeClass.isEnum()) { int length = java.lang.reflect.Array.getLength(array); @@ -121,7 +106,6 @@ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor sessi return result; } - @Override public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException { if (value == null) { st.setNull(index, Types.ARRAY); @@ -145,22 +129,22 @@ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionIm valueToSet = converted; } - Array array = st.getConnection().createArrayOf(PgArrayUtils.getNativeSqlType(typeClass), (Object[]) typeArrayClass.cast(valueToSet)); + java.sql.Array array = st.getConnection().createArrayOf(PgArrayUtils.getNativeSqlType(typeClass), (Object[]) typeArrayClass.cast(valueToSet)); st.setArray(index, array); } public Class getTypeClass() { - return this.typeClass; + return typeClass; } - private Object idToEnum(Object id) throws HibernateException, SQLException { + private Object idToEnum(Object id) throws HibernateException { try { if (bidiMap == null) { - bidiMap = new BidiEnumMap(this.typeClass); + bidiMap = new BidiEnumMap(typeClass); } return bidiMap.getEnumValue(id); } catch (Exception e) { - throw new HibernateException("Unable to create bidirectional enum map for " + typeClass + " with nested exception: " + e.toString()); + throw new HibernateException("Unable to create bidirectional enum map for " + typeClass, e); } } } diff --git a/src/java/net/kaleidos/hibernate/usertype/BidiEnumMap.java b/src/java/net/kaleidos/hibernate/usertype/BidiEnumMap.java index 479e714..14fba7d 100644 --- a/src/java/net/kaleidos/hibernate/usertype/BidiEnumMap.java +++ b/src/java/net/kaleidos/hibernate/usertype/BidiEnumMap.java @@ -11,6 +11,7 @@ import java.util.HashMap; import java.util.Map; +@SuppressWarnings({ "unchecked", "rawtypes" }) public class BidiEnumMap implements Serializable { private static final long serialVersionUID = 3325751131102095834L; @@ -22,7 +23,7 @@ public class BidiEnumMap implements Serializable { public BidiEnumMap(Class enumClass) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Building Bidirectional Enum Map...")); + LOG.debug("Building Bidirectional Enum Map..."); } EnumMap enumToKey = new EnumMap(enumClass); diff --git a/src/java/net/kaleidos/hibernate/usertype/HstoreHelper.java b/src/java/net/kaleidos/hibernate/usertype/HstoreHelper.java index 9047746..11e2511 100644 --- a/src/java/net/kaleidos/hibernate/usertype/HstoreHelper.java +++ b/src/java/net/kaleidos/hibernate/usertype/HstoreHelper.java @@ -8,8 +8,7 @@ import java.util.Map; /** - * Helper class to convert Maps to String according to hstore syntax - * and vice versa + * Converts Maps to String and vice versa according to hstore syntax. */ public class HstoreHelper { @@ -59,28 +58,27 @@ public static String asStatement(Map m) { public static List asListKeyValue(Map m) { List result = new LinkedList(); if (m != null && !m.isEmpty()) { - for (String key : m.keySet()) { - result.add(key); - result.add(String.valueOf(m.get(key))); + for (Map.Entry entry : m.entrySet()) { + result.add(entry.getKey()); + result.add(entry.getValue()); } } return result; } + @SuppressWarnings("rawtypes") public static HstoreDomainType toHstoreDomainType(String s) { Map m = HstoreHelper.toMap(s); return new HstoreDomainType(m); } + @SuppressWarnings("rawtypes") public static Map toMap(String s) { - Map m = new HashMap(); if (s == null || s.equals("")) { - return m; + return new HashMap(); } HstoreParser parser = new HstoreParser(s); - m = parser.asMap(); - - return m; + return parser.asMap(); } } diff --git a/src/java/net/kaleidos/hibernate/usertype/HstoreParseException.java b/src/java/net/kaleidos/hibernate/usertype/HstoreParseException.java index 3b7affa..cf1ab29 100644 --- a/src/java/net/kaleidos/hibernate/usertype/HstoreParseException.java +++ b/src/java/net/kaleidos/hibernate/usertype/HstoreParseException.java @@ -1,6 +1,8 @@ package net.kaleidos.hibernate.usertype; -public class HstoreParseException extends Throwable { +public class HstoreParseException extends RuntimeException { + + private static final long serialVersionUID = 1; public HstoreParseException(String error, int position) { super("Error @" + position + " : " + error); diff --git a/src/java/net/kaleidos/hibernate/usertype/HstoreParser.java b/src/java/net/kaleidos/hibernate/usertype/HstoreParser.java index 5b64102..e7605f8 100644 --- a/src/java/net/kaleidos/hibernate/usertype/HstoreParser.java +++ b/src/java/net/kaleidos/hibernate/usertype/HstoreParser.java @@ -8,6 +8,8 @@ import java.util.Map.Entry; import java.util.NoSuchElementException; +import org.springframework.util.Assert; + /** * This class is an extended version of HStore.java from https://code.google.com/p/pg-spring-type-mapper/ */ @@ -25,9 +27,7 @@ public HstoreParser(String rawValue) { @Override public void setValue(String rawValue) { - if (!"hstore".equals(this.type)) { - throw new IllegalStateException("HStore database type name should be 'hstore'"); - } + Assert.state("hstore".equals(type), "HStore database type name should be 'hstore'"); this.value = rawValue; this.length = rawValue == null ? 0 : rawValue.length(); } @@ -54,17 +54,14 @@ private static class HStoreEntry implements Entry { this.value = value; } - @Override public String getKey() { return key; } - @Override public String getValue() { return value; } - @Override public String setValue(String value) { final String oldValue = this.value; this.value = value; @@ -94,7 +91,6 @@ public HStoreIterator() throws HstoreParseException { advance(); } - @Override public boolean hasNext() { return nextEntry != null; } @@ -108,7 +104,6 @@ private HStoreEntry rawNext() throws NoSuchElementException, HstoreParseExceptio return lastReturned; } - @Override public Entry next() throws NoSuchElementException, IllegalStateException { try { return rawNext(); @@ -151,16 +146,18 @@ private void advance() throws HstoreParseException { if (ch == EQUALS) { state = ParseState.WaitingForGreater; continue; - } else { - throw new HstoreParseException("Expected '=>' key-value separator", position); } + + throw new HstoreParseException("Expected '=>' key-value separator", position); + case WaitingForGreater: if (ch == GREATER) { state = ParseState.WaitingForValue; continue; - } else { - throw new HstoreParseException("Expected '=>' key-value separator", position); } + + throw new HstoreParseException("Expected '=>' key-value separator", position); + case WaitingForValue: if (Character.isWhitespace(ch)) continue; for (char q : QUOTE) { @@ -185,9 +182,10 @@ private void advance() throws HstoreParseException { if (ch == COMMA) { // we are done break loop; - } else { - throw new HstoreParseException("Cannot find comma as an end of the value", position); } + + throw new HstoreParseException("Cannot find comma as an end of the value", position); + default: throw new IllegalStateException("Unknown HstoreParser state"); } @@ -234,10 +232,10 @@ private String advanceQuoted() throws HstoreParseException { // or we could not find the next quote insideQuote = false; break; - } else { - if (sb != null) { - sb.append(ch); - } + } + + if (sb != null) { + sb.append(ch); } } if (insideQuote) { @@ -246,9 +244,9 @@ private String advanceQuoted() throws HstoreParseException { if (sb == null) { // we consumed the last quote return value.substring(firstQuotePosition + 1, position); - } else { - return sb.toString(); } + + return sb.toString(); } private String advanceWord(final char stopAtChar) throws HstoreParseException { @@ -257,7 +255,8 @@ private String advanceWord(final char stopAtChar) throws HstoreParseException { final char ch = value.charAt(position); if (ch == currentQuoteChar) { throw new HstoreParseException("Unexpected quote in word", position); - } else if (Character.isWhitespace(ch) || ch == stopAtChar) { + } + if (Character.isWhitespace(ch) || ch == stopAtChar) { break; } position++; @@ -268,13 +267,11 @@ private String advanceWord(final char stopAtChar) throws HstoreParseException { return value.substring(firstWordPosition, position + 1 ); } - @Override public void remove() { throw new UnsupportedOperationException(); } } - @Override public Iterator> iterator() { try { return new HStoreIterator(); @@ -282,4 +279,4 @@ public Iterator> iterator() { throw new IllegalStateException(e); } } -} \ No newline at end of file +} diff --git a/src/java/net/kaleidos/hibernate/usertype/JsonMapType.java b/src/java/net/kaleidos/hibernate/usertype/JsonMapType.java index df71754..1bbf376 100644 --- a/src/java/net/kaleidos/hibernate/usertype/JsonMapType.java +++ b/src/java/net/kaleidos/hibernate/usertype/JsonMapType.java @@ -24,33 +24,27 @@ public class JsonMapType implements UserType { private final Gson gson = new GsonBuilder().create(); - @Override public int[] sqlTypes() { return new int[]{SQLTYPE}; } - @Override - public Class returnedClass() { + public Class returnedClass() { return userType.getClass(); } - @Override public boolean equals(Object x, Object y) throws HibernateException { return ObjectUtils.equals(x, y); } - @Override public int hashCode(Object x) throws HibernateException { return x == null ? 0 : x.hashCode(); } - @Override public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException { String jsonString = rs.getString(names[0]); return gson.fromJson(jsonString, userType); } - @Override public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException { if (value == null) { st.setNull(index, Types.OTHER); @@ -59,37 +53,29 @@ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionIm } } - @Override + @SuppressWarnings({ "rawtypes", "unchecked" }) public Object deepCopy(Object value) throws HibernateException { - if (value != null) { - Map m = (Map) value; - - if (m == null) { - m = new HashMap(); - } - return new HashMap(m); - } else { - return null; + if (value == null) { + return null; } + + Map m = (Map) value; + return new HashMap(m); } - @Override public boolean isMutable() { return true; } - @Override public Serializable disassemble(Object value) throws HibernateException { return gson.toJson(value, userType); } - @Override public Object assemble(Serializable cached, Object owner) throws HibernateException { return gson.fromJson((String) cached, userType); } - @Override public Object replace(Object original, Object target, Object owner) throws HibernateException { return original; } -} \ No newline at end of file +} diff --git a/src/java/net/kaleidos/hibernate/utils/PgArrayUtils.java b/src/java/net/kaleidos/hibernate/utils/PgArrayUtils.java index adae58d..11aab11 100644 --- a/src/java/net/kaleidos/hibernate/utils/PgArrayUtils.java +++ b/src/java/net/kaleidos/hibernate/utils/PgArrayUtils.java @@ -1,14 +1,26 @@ package net.kaleidos.hibernate.utils; -import org.hibernate.HibernateException; - import java.lang.reflect.Array; +import java.util.HashMap; import java.util.List; +import java.util.Map; + +import org.hibernate.HibernateException; /** - * Protected class with utils for the different criteria queries + * Utils for the different criteria queries. */ public class PgArrayUtils { + + private static final Map, String> CLASS_TO_TYPE_NAME = new HashMap, String>(); + static { + CLASS_TO_TYPE_NAME.put(Integer.class, "int"); + CLASS_TO_TYPE_NAME.put(Long.class, "int8"); + CLASS_TO_TYPE_NAME.put(String.class, "varchar"); + CLASS_TO_TYPE_NAME.put(Float.class, "float"); + CLASS_TO_TYPE_NAME.put(Double.class, "float8"); + } + /** * Returns a new array wrapping the parameter value. The type of the array * will be the type passed as parameter @@ -26,12 +38,12 @@ public static Object[] getValueAsArrayOfType(Object targetValue, Class expect List valueAsList = (List) targetValue; arrValue = (Object[]) Array.newInstance(expectedType, valueAsList.size()); - // We will iterate the collection and if the value it's not a valid value we throw the exception - for (int i = 0; i < valueAsList.size(); i++) { - if (expectedType.isInstance(valueAsList.get(i))) { - arrValue[i] = expectedType.cast(valueAsList.get(i)); + for (int i = 0, count = valueAsList.size(); i < count; i++) { + Object object = valueAsList.get(i); + if (expectedType.isInstance(object)) { + arrValue[i] = expectedType.cast(object); } else if (mapFunction != null) { - arrValue[i] = expectedType.cast(mapFunction.map(valueAsList.get(i))); + arrValue[i] = expectedType.cast(mapFunction.map(object)); } else { throw new HibernateException("criteria doesn't support values of type: " + targetValue.getClass().getName() + ". Try: " + expectedType + " or List<" + expectedType + "> instead"); @@ -62,38 +74,28 @@ public static Object[] getValueAsArrayOfType(Object targetValue, Class expect } /** - * Simple class for passing a closure that takes an Object and transforms it into a new value. + * Takes an Object and transforms it into a new value. */ - public static abstract class MapFunction { + public interface MapFunction { /** * Transforms an object into some new value. * - * @param o the object we want to transform - * @return some transformed version of the object + * @param o the object + * @return some new value */ - public abstract Object map(Object o); + Object map(Object o); } - public static String getNativeSqlType(Class clazz) { - if (Integer.class.equals(clazz) || clazz.isEnum()) { - return "int"; - } - - if (Long.class.equals(clazz)) { - return "int8"; + public static String getNativeSqlType(Class clazz) { + String typeName = CLASS_TO_TYPE_NAME.get(clazz); + if (typeName != null) { + return typeName; } - if (String.class.equals(clazz)) { - return "varchar"; - } - - if (Float.class.equals(clazz)) { - return "float"; + if (clazz.isEnum()) { + return "int"; } - if (Double.class.equals(clazz)) { - return "float8"; - } throw new RuntimeException("Type class not valid: " + clazz); } } From c624c5f79ee83ed784c7e507e15ca43aa656f813 Mon Sep 17 00:00:00 2001 From: Burt Beckwith Date: Fri, 19 Dec 2014 23:33:18 -0500 Subject: [PATCH 3/3] there's no need to exclude hibernate, it's not exported --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index df709f0..4366f03 100644 --- a/README.md +++ b/README.md @@ -48,9 +48,7 @@ In `BuildConfig.groovy` add the following to install the plugin: ```groovy plugins { ... - compile (":postgresql-extensions:") { - excludes "hibernate" - } + compile ":postgresql-extensions:" ... } ``` @@ -61,7 +59,7 @@ Please note that you also have to install the Grails Hibernate plugin: [Hibernat plugins { // Hibernate 4 compile ":hibernate4:4.3.5.5" - + // Hibernate 3 compile ":hibernate:3.6.10.17" }