TAGS :Viewed: 3 - Published at: a few seconds ago

[ new domain object created with grails console not visible in dbconsole ]

I am trying to create a new domain object in the grails console with the help of this guide. According to the console output the new object is created:

grails> shell
groovy:000> new foo.Book(title: 'bar').save(failOnError: true, flush: true)
groovy:000> foo.Book : 1
groovy:000> foo.Book.list()
groovy:000> [foo.Book : 1]

But this new book entity is not visible in the dbconsole The table BOOK is present when I connect with the JDBC url for the dev environment as found in DataSource.groovy:

jdbc:h2:mem:devDb;MVCC=TRUE
username: sa
password: <blank>

but a select returns 0 rows

The relevant piece of DataSource.groovy config (the default)

dataSource {
    pooled = true
    driverClassName = "org.h2.Driver"
    username = "sa"
    password = ""
}
hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = false
    cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory' // Hibernate 3
//    cache.region.factory_class = 'org.hibernate.cache.ehcache.EhCacheRegionFactory' // Hibernate 4
}

// environment specific settings
environments {
    development {
        dataSource {
            dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
            url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
        }
    }

When the entity is created using the console, rather than the groovy shell, the issue remains.

I am using the newest grails build at this moment, which is 2.3.1
The embedded H2 database vrsion = H2 1.3.173 (2013-07-28)

Answer 1


I think the problem is that the database is getting locked. Let's try this one then (works on my experiment):

edit your grails-app/conf/spring/resources.groovy and make it looking like this:

// Place your Spring DSL code here
beans = {
    h2Server(org.h2.tools.Server, "-tcp,-tcpPort,8043") { bean ->
        bean.factoryMethod = "createTcpServer"
        bean.initMethod = "start"
        bean.destroyMethod = "stop"
    }
}

Then, modify your grails-app/conf/DataSource.groovy to look like this:

test {
        dataSource {
            dbCreate = "update"
            url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
        }
}

Now, you are ready to add some new objects as per the tutorial:

$ grails
grails> run-app
grails> shell
groovy:000> new test.Book(title: 'Book 1').save(failOnError: true)
===> test.Book : 1
groovy:000> new test.Book(title: 'Book 2').save(failOnError: true)
===> test.Book : 2
groovy:000> test.Book.list()
===> [test.Book : 1, test.Book : 2]

To view the H2 console, go to

http://localhost:8080/{project}/dbconsole 

but select [Generic H2 Server] from the list and on the JDBC URL enter:

jdbc:h2:tcp://localhost:8043/mem:devDb 

and connect. I hope that helps

======================

After a bit further experimentation, it appears that locking was your problem and you need to use a mixed mode approach when connecting to your H2. You can read more information here:

http://www.h2database.com/html/features.html#auto_mixed_mode

So, the simplest thing to do is use this jdbc connection URL:

url = "jdbc:h2:/tmp/myDB;MVCC=TRUE;LOCK_TIMEOUT=10000;AUTO_SERVER=TRUE"

for both your application and the H2 dbconsole (notice the AUTO_SERVER=TRUE) (no need to modify the spring bean)

Answer 2


I suggest to change the

dbCreate = "create-drop"

to

dbCreate = "update"

on your DataSource.groovy and try again

Answer 3


When I modified the spring bean as Nick suggested, I could not start run-app and at the same time start the grails console or shell. Here is the error I got:

Message: Error creating bean with name 'h2Server': Invocation of init method failed; nested exception is org.h2.jdbc.JdbcSQLException: Exception opening port "8043" (port may be in use), cause: "java.net.BindException: Address already in use" [90061-173]

The simple change to url worked, thanks Nick -:)