Reputation: 13811
I have mysql table named anto2
. Which has only one column name
of varchar 100
. I tried to map this table in grails domain class :
class Anto {
String grailsName
static constraints = {
}
static mapping = {
table 'anto2'
grailsName column: 'name'
}
}
After I did run-app
I can see my table have been added with two more columns :
+---------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| name | varchar(100) | YES | | NULL | |
| id | bigint(20) | NO | | NULL | |
| version | bigint(20) | NO | | NULL | |
+---------+--------------+------+-----+---------+-------+
I generated static view and controller for this Domain class and when I tried to save it , I get an error in my save()
method (which is generated using generate-all
command). The error is as follows :
2012-07-09 23:05:26,391 [http-bio-8080-exec-2] ERROR errors.GrailsExceptionResolver - SQLException occurred when processing request: [POST] /mysql/anto/save - parameters:
create: Create
Field 'id' doesn't have a default value. Stacktrace follows:
Message: Field 'id' doesn't have a default value
Line | Method
->> 1073 | createSQLException in com.mysql.jdbc.SQLError
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 3597 | checkErrorPacket in com.mysql.jdbc.MysqlIO
| 3529 | checkErrorPacket . in ''
| 1990 | sendCommand in ''
| 2151 | sqlQueryDirect . . in ''
| 2625 | execSQL in com.mysql.jdbc.ConnectionImpl
| 2119 | executeInternal . in com.mysql.jdbc.PreparedStatement
| 2415 | executeUpdate in ''
| 2333 | executeUpdate . . in ''
| 2318 | executeUpdate in ''
| 105 | executeUpdate . . in org.apache.commons.dbcp.DelegatingPreparedStatement
| 25 | save in mnm.AntoController
| 1110 | runWorker . . . . in java.util.concurrent.ThreadPoolExecutor
| 603 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . . . . . in java.lang.Thread
Why does this happen? Where I went wrong?
Upvotes: 1
Views: 5380
Reputation: 3407
If you don't specify your kind of id generator, GORM will use the native strategy of your database.If you're using mysql as db, it will create your ids using IDENTITY strategy to generate them. This strategy requires to have an auto increment on your id column.
Although I think defining a strategy is better. You can use the SEQUENCE strategy:
id column:'id_anto2', generator:'sequence', params:[sequence:'tab_anto2_seq']
and then create a sequence with that same name in your database (so you don't have to use the one Hibernate creates for you automatically). It's very easy and works like a charm.
Also, to discard the version field, insert version false in your mapping block. So, it would be like:
static mapping = {
table 'anto2'
id column: 'id_anto2', generator: 'sequence', params: [sequence:'tab_anto2_seq']
grailsName column: 'name'
version false
}
Upvotes: 3
Reputation: 493
It looks like you are missing id mapping. Try adding an id reference to your static mapping closure. Also, if this is an existing database you might want to set the version to false or grails might try to alter the table with a version column, depending on how you have datasource.groovy set up.
table 'anto2'
version false
id column:'anto2_ID'
grailsName column: 'name'
Upvotes: 0