3

I need to run a Grails 3 app against MySql/Hibernate and MongoDB. (Had is running on Grails 2.5 without an hitch).

I tried many different combinations, searched and tried related SO answers, but with no luck.

Used the latest Mongodb plugin doc for the configuration.

Using Grails 3.1.10:

grailsVersion=3.1.10

I started with the following details in build.gradle:

buildscript {
  ext {
    grailsVersion = project.grailsVersion
  }
  repositories {
    mavenLocal()
    maven { url "https://repo.grails.org/grails/core" }
  }
  dependencies {
    classpath "org.grails:grails-gradle-plugin:$grailsVersion"
    classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.8.2"
    classpath "org.grails.plugins:hibernate4:5.0.10"
  }
}
...
dependencies {
  compile "org.springframework.boot:spring-boot-starter-logging"
  compile "org.springframework.boot:spring-boot-autoconfigure"
  compile "org.grails:grails-core"
  compile "org.springframework.boot:spring-boot-starter-actuator"
  compile "org.springframework.boot:spring-boot-starter-tomcat"
  compile "org.grails:grails-dependencies"
  compile "org.grails:grails-web-boot"
  compile "org.grails.plugins:cache"
  compile "org.grails.plugins:scaffolding"
  compile "org.grails.plugins:hibernate4"
  compile "org.hibernate:hibernate-ehcache"
  console "org.grails:grails-console"
  profile "org.grails.profiles:web"

  runtime "com.bertramlabs.plugins:asset-pipeline-grails:2.8.2"

  testCompile "org.grails:grails-plugin-testing"
  testCompile "org.grails.plugins:geb"
  testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1"
  testRuntime "net.sourceforge.htmlunit:htmlunit:2.18"

  //databases
  compile 'org.grails.plugins:mongodb:6.0.0.M2'
  runtime 'mysql:mysql-connector-java:5.1.36'
  ...
 }

The application.yml:

---
hibernate:
  cache:
    queries: false
    use_second_level_cache: true
    use_query_cache: false
    region.factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory

dataSource:
  pooled: true
  jmxExport: true
  driverClassName: com.mysql.jdbc.Driver

environments:
  development:
    dataSource:
        dbCreate: update
        url: jdbc:mysql://localhost:3306/dbname
        driverClassName: com.mysql.jdbc.Driver
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect
        username : "xxx"
        password : "yyy"
        properties:
            maxActive : 50
            maxIdle: 25
            minIdle: 5
            ...
   grails:
     mongodb:
       host: "localhost"
       port: 27017
       username: "blah"
       password: "blah"
       databaseName: "foo"

Now this gives me an error:

15:13:58.001 [QUIET] [system.out] ERROR     org.springframework.boot.SpringApplication - Application startup failed
15:13:58.001 [QUIET] [system.out] java.lang.NoClassDefFoundError: org/grails/datastore/gorm/plugin/support/ConfigSupport
15:13:58.001 [QUIET] [system.out]   at grails.plugins.mongodb.MongodbGrailsPlugin.doWithSpring(MongodbGrailsPlugin.groovy:42)

The MongoDB grails plugin does not find ConfigSupport

ConfigSupport.prepareConfig(config, (ConfigurableApplicationContext) applicationContext)

I then tried to add the following plugins in all orders possible:

//compile 'org.grails:grails-datastore-gorm-hibernate4:6.0.0.M2'
//compile 'org.grails:grails-datastore-core:4.0.0.M2'
//compile 'org.grails:grails-datastore-gorm-plugin-support:6.0.0.M2'
//compile 'org.springframework.data:spring-data-mongodb:1.9.2.RELEASE'
//compile 'org.mongodb:mongodb-driver:3.3.0'
//compile 'org.mongodb:mongo-java-driver:3.3.0'

No luck.

I also moved the mongodb: section down to the grails: section in the yml file. Same error.

So the question is how to get MongoDB running with MySql with grails3.

3 Answers3

2

Ok, stupid me. I solved the puzzle using these simple dependency settings:

compile "org.springframework.boot:spring-boot-starter-logging"
compile "org.springframework.boot:spring-boot-autoconfigure"
compile "org.grails:grails-core"
compile "org.springframework.boot:spring-boot-starter-actuator"
compile "org.springframework.boot:spring-boot-starter-tomcat"
compile "org.grails:grails-dependencies"
compile "org.grails:grails-web-boot"
compile "org.grails.plugins:cache"
compile "org.grails.plugins:scaffolding"
compile "org.grails.plugins:hibernate4"
compile "org.hibernate:hibernate-ehcache"
console "org.grails:grails-console"
profile "org.grails.profiles:web"
runtime "com.bertramlabs.plugins:asset-pipeline-grails:2.8.2"
testCompile "org.grails:grails-plugin-testing"
testCompile "org.grails.plugins:geb"
testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1"
testRuntime "net.sourceforge.htmlunit:htmlunit:2.18"

//databases
compile 'org.grails.plugins:mongodb'
runtime 'mysql:mysql-connector-java:5.1.36'

runtime 'com.googlecode.json-simple:json-simple:1.1'

It seems that the following line made the difference:

compile 'org.grails.plugins:mongodb'

Omitting the version number. This should be explained in the docs a bit better. Usually it is a good thing defining versions, or is this too old fashioned these days? :-)

Happy to have it working

1

Ok I found correct previous answer for referring mongodb plugin, i.e.
compile 'org.grails.plugins:mongodb'
but I want to sum up with a brief checklist, having me a correctly running mixed solution (both hibernate + mysql and mongodb), after many trials and errors.
So, in order to have a mixed mysql/mongo grails3 configuration, you have to

  1. insert compile 'org.grails.plugins:mongodb' (without any version) in build.gradle (remember that there is no BuildConfig.groovy in grails 3, as documented here/grails2->3)
  2. keep ordinary dependency to hibernate/mysql, for example: compile 'org.grails.plugins:hibernate4' compile 'org.hibernate:hibernate-ehcache' runtime 'mysql:mysql-connector-java:5.1.38'
  3. set up correctly connections in application.yml, but I prefer old-style application.groovy, in grails-app/conf (as in older GRAILS), as below (remember that in GRAILS3 differently from 2 you have to use mongodb and no more mongo keyword)
  4. use ordinary GRAILS entities for mysql mapping
  5. and use static mapWith="mongo" inside mongo entities (as stated in GRAILS-mongo doc)
  6. not use usual mysql Long id for mongo, but ObjectId id, and for it import org.bson.types.ObjectId


Application.groovy set up

grails {   
  mongodb {
        host = "localhost"
        port = 27017
        username = mongouser 
        password= mongopasswd 
        databaseName = mongoDBname
      }
}
environments {
  development {
    dataSource {
      driverClassName = "com.mysql.jdbc.Driver"
      username = ...
      password = ...
      dbCreate = "create"
      url = "jdbc:mysql://127.0.0.1:3306/dbnameMysql"
    }
  }
} 

That's all. Enjoy MongoDB.

0

Not sure I can help much other than show my config that is confirmed working. I've recently converted a 2.4.4 app to 3.1.8, admittedly I'm using Oracle as my RDBMS rather than mysql.

In build.gradle I just have:

dependencies {
classpath "org.grails.plugins:hibernate4:5.0.6"
...
}

dependencies {
compile "org.grails.plugins:mongodb:5.0.0.RC1"
...
}

And in application.yml:

mongodb:
    databaseName: 'myApp'
    engine: mapping

The engine: mapping bit was crucial for me, it reverts to the previous persistence engine as described here http://gorm.grails.org/latest/mongodb/manual/index.html

The doWithSpring() closure in my MongodbGrailsPlugin.groovy looks like:

Closure doWithSpring() {
def initializer = new MongoDbDataStoreSpringInitializer(config,     grailsApplication.getArtefacts(DomainClassArtefactHandler.TYPE).collect() {     GrailsClass cls -> cls.clazz })
initializer.registerApplicationIfNotPresent = false
initializer.setSecondaryDatastore( manager.hasGrailsPlugin("hibernate")  )
return     initializer.getBeanDefinitions((BeanDefinitionRegistry)applicationContext)
}

No reference to ConfigSupport which may have been added (or not) in your later version or there's a dependency missing.

Mike W
  • 3,853
  • 2
  • 11
  • 18