My Grails application and bootstrap work fine when dbCreate="create", but when I change it to dbCreate="update", I get object create validation errors in bootstrap. I'd just like my data to persist when I restart the application. From the error message, it appears I'm violating a unique constraints. Maybe the database isn't getting purged on restart? I've tried "create-drop"
Here is the code and error message below. Any insight is appreciated.
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
url = "jdbc:h2:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;"
}
}
class BootStrap {
def init = { servletContext ->
def adminRole = new com.testapp.Role(authority: 'ROLE_ADMIN').save(failOnError: true)
def userRole = new com.testapp.Role(authority: 'ROLE_USER').save(failOnError: true)
}
Message:
Validation Error(s) occurred during save():
- Field error in object 'com.testapp.Role' on field 'authority': rejected value [ROLE_ADMIN]; codes [com.testapp.Role.authority.unique.error.
default message [Property [{0}] of class [{1}] with value [{2}] must be unique
I think you must have already created the Role with Authority "ROLE_ADMIN" or "ROLE_USER". The second time you are running with update gives an error because of unique constraint. An attempt is being made to create role with same Authority names and it throws error.
You should apply a condition such that if a role already exist, you should not try to create the same again.
Related
I reached next problem after upgrade grails 2.2.1 to 2.3.6
I think any of my Command object in controllers not working for example:
I had Command Object like that:
#ToString
#grails.validation.Validateable
class ListUserRoleCommand {
String userId
User getUser() { User.get(userId) }
static constraints = {
userId nullable: false
user nullable: false
}
}
I had entry in UrlMapping.groovy:
"/user/$userId/role"(controller: "userRole", parseRequest: true) { action = [GET: "list", POST: "save"] }
That shoud bind request: my-app/user/4324gf54f4f34r3ff/role with command object in controller UserRoleController and 'list' action (I'm sending GET method)
But I getting validation exception on userId.
Field error in object 'pl.fissst.invoice.security.ListUserRoleCommand' on field 'userId': rejected value [null]
I'm println $params to console and I had correct data:
params: [userId:ff808181458ff92401458ff94e150005, action:[GET:list, POST:save], controller:userRole, start:0, end:24, count:25, sort:[:], filter:[:]]
I checked other parts in application, and I'm think that other command objects not working too.
I had that entries in Config.groovy:
grails.databinding.convertEmptyStringsToNull = false
grails.databinding.trimStrings = false
so that isn't problem of empty sting.
Anyone can help ?
EDIT1:
One more think. If I set in Config.groovy:
grails.databinding.useSpringBinder = false
application starts works almost properly. Now only some commands not work. But If I set grails.databinding.useSpringBinder to true, I think any of command object not wok.
Why partial of command objects stop working ?
EDIT2:
I noticed that command object has bind partial data.
I noticed too, that this part of data which was binded is comming from post data , but this part whih is comming was missed from url (Urlmapping url params like $id)
EDIT3:
For above:
I looking on a Web, and I found some threads where people says that :
parseRequest
from Urlmapping not work anymore in grils 2.3.x. Is that true ? How can I handle that ?
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)
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)
I suggest to change the
dbCreate = "create-drop"
to
dbCreate = "update"
on your DataSource.groovy and try again
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 -:)
I have the following settings on a new grails project:
dataSource {
pooled = true
driverClassName = "com.mysql.jdbc.Driver"
dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
username = "sa"
password = ""
}
environments {
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
url = "jdbc:mysql://localhost/myapp?useUnicode=yes&zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8"
username = "root"
password = ""
}
}
}
when I run my app it fails with an error: Error creating bean with name 'transactionManagerPostProcessor':
This error goes away when I manually go to my database and create a database called myapp
I thought the create-drop setting in dbCreate is suppose to create the db if it does not exist.
Question
How can I configure the settings so that the database gets created when it does not exist in the MySQL
Creating the database itself is impractical because it is very vendor-specific, even more so than the DDL to create tables, sequences, etc. You often need to specify access rules, storage options, etc.
Hibernate will generate and run the schama DDL but you have to start the process by creating the database itself except for simple databases like H2.
We are using grails with groovy and recently changed database from MySQL to Oracle 11g. We took care of table names like USER, RESOURCE to make it something else, remapped the new names in the domain classes.
I also added some default data in roles from mysql table(for spring security to work) and inserted one user 'admin' manually in GRAUSER table (renamed from USER).
The server does start up in Netbeans
But when I try to login I get the following error
ERROR util.JDBCExceptionReporter ORA-00904: "THIS_"."password": invalid identifier
Not able to debug the cause of this. Let me know if any more details/code is needed to review, but I need to be able to login to the application.
Could you post your DataSource.groovy file? Below is roughly what mine looks like for connecting to Oracle.
dataSource {
logsql = true
pooled = true
driverClassName = "oracle.jdbc.OracleDriver"
username = "user"
password = "secret"
dialect='org.hibernate.dialect.Oracle10gDialect'
}
environments {
development {
dataSource {
//dbCreate = "create-drop" // one of 'create', 'create-drop','update'
url = "jdbc:oracle:thin:#server:1521:sid"
}
}
}
I'm somewhat new to Grails. As I create or update domain object and fire save() or validate() on an object, if the method fails, the system does not seem throw an exception. I dont see any way to examine what exactly is failing.
A typical snippet:
if (domainInstance.validate()) {
flash.message = "Succesfully updated domain object"
} else {
flash.message = "Failed to update domain object"
//throw new RuntimeException("Invalid broker")
log.error "Failed to update domain object"
}
In my case the validate fails, and I am in the dark as to why.
Could anybody shed some light on it?
If placed into a try/catch, this does not throw an exception.
mydomain.validate() is used to only validate the object. You may use mydomain.hasErrors() to load the errors object and to print what went wrong with the following statement.
if(mydomain.hasErrors()){
mydomain.errors.allErrors.each{println it}
}
And generally the way I prefer to save and update any object is
if(mydomain.hasErrors() || !mydomain.save(failOnError:true){
//action to be taken if domain validation fails.
}
By setting failOnError:true, if the save() fails, validation exception would be thrown which needs to catched in controller.
You can also set failOnError = true for the entire application in the grails config file
grails.gorm.failOnError=true
http://www.grails.org/doc/1.3.x/guide/3.%20Configuration.html#3.1.3 GORM