简体   繁体   中英

How to map mysql table to Grails domain class?

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?

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
}

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'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM