How to map mysql table to Grails domain class? - mysql

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'

Related

Querying a json field in mysql using JOOQ

I have a transaction table and it has a json type field called "request".
| Field | Type | Null | Key | Default |
| id | bigint | NO | PRI | NULL |
| request | json | NO | | NULL |
| response | json | YES | | NULL |
request has two attributes currencyCode and amount.
{"amount":100000,"currencyCode":"PHP"}
I can use following mysql query to fetch these values
select json_extract(request, "$.amount") as amount, json_extract(request, "$.currencyCode") as currency from transaction;
| amount | currency |
+--------+----------+
| 100000 | PHP |
| 100000 | PHP |
| 100000 | PHP |
I want to get these values using a jooq query something like this.
DSL.select(<Tables.TRANSACTION.REQUEST.amount>, <Tables.TRANSACTION.REQUEST.currencyCode>)
.from(Tables.TRANSACTION)
.fetch()
I really appreciate if someone can help me with this.
Using jOOQ 3.14's JSON_VALUE support
Starting with jOOQ 3.14, you will be able to use the new built-in standard JSON operator support, e.g. JSON_VALUE(). As per the docs:
This example using jOOQ:
jsonValue(val(JSON.json("[1,2]")), "$[*]")
Translates to the following dialect specific expressions:
...
-- MYSQL
json_extract('[1,2]', '$[*]')
Using plain SQL templating in jOOQ 3.13 and earlier
Whenever jOOQ doesn't support vendor specific functionality out of the box, you can resort to using plain SQL templating. Just write:
public static Field<String> jsonExtract(Field<?> field, String jsonPath) {
return DSL.field("json_extract({0}, {1})", String.class, field, DSL.inline(jsonPath));
}

Slick 3.2: Unable to perform upsert operation using mysql

I am using slick 3.2 for creating simple CRUD application, but while performing upsert operations, the record is not updated. But in logs, it seems like, the record is updated. Following is my code:
private val product = TableQuery[Products]
override def updateProduct(id: Int, row: ProductsRow): Future[Int] = db.run {
product.insertOrUpdate(row)
}
ProductsRow(3,'PULLY','DDD',new TimeStamp(new Data().getTime), 4, 202, -1)
My Logs are:
[debug] s.j.J.statement - Preparing statement: insert into `mae_app`.`products` (`id`,`name`,`code`,`date`,`quantity`,`price`,`company_id`) values (?,?,?,?,?,?,?) on duplicate key update `name`=VALUES(`name`), `code`=VALUES(`code`), `date`=VALUES(`date`), `quantity`=VALUES(`quantity`), `price`=VALUES(`price`), `company_id`=VALUES(`company_id`)
[debug] s.j.J.parameter - /-----+--------+--------+-------------------------+-----+------------+-----\
[debug] s.j.J.parameter - | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
[debug] s.j.J.parameter - | Int | String | String | Timestamp | Int | BigDecimal | Int |
[debug] s.j.J.parameter - |-----+--------+--------+-------------------------+-----+------------+-----|
[debug] s.j.J.parameter - | 3 | PULLY | DDD | 2017-08-03 10:17:47.144 | 4 | 205.0 | -1 |
[debug] s.j.J.parameter - \-----+--------+--------+-------------------------+-----+------------+-----/
The logs seems like, record is updated with new values, but while we are check into database, db still have old record values.
It seems like, generated sql query is not correct like on duplicate key updatename=VALUES(name) statement contains name filed, rather then name field value. I am not able to figure out, what exact problem is? So, how to resolve the problem?

"Duplicate entry '' for key" in Grails Database Migration using hasOne

Using Grails Database Migration Plugin 1.4 I want have the following structure of my existing database:
class StickerGroup {
}
Now I added the class Company and updated the class StickerGroup:
class StickerGroup {
static constraints = { company nullable: true, unique: true }
static belongsTo = [company: Company]
}
class Company {
static hasOne = [stickerGroup: StickerGroup]
}
I created the migration file and then I perform grails dbm-update. After that I get the following error log:
2015-01-20 15:03:49,549 [main] ERROR liquibase - Change Set 2015-01-20-update-Company.groovy::1421762562430-2::mg (generated) failed. Error: Error executing SQL ALTER TABLE `sticker_group` ADD `company_id` VARCHAR(10) NOT NULL UNIQUE: Duplicate entry '' for key 'company_id'
Message: Error executing SQL ALTER TABLE `sticker_group` ADD `company_id` VARCHAR(10) NOT NULL UNIQUE: Duplicate entry '' for key 'company_id'
Line | Method
->> 62 | execute in liquibase.executor.jvm.JdbcExecutor
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 104 | execute in ''
| 1091 | execute . . . . . in liquibase.database.AbstractDatabase
| 1075 | executeStatements in ''
| 317 | execute . . . . . in liquibase.changelog.ChangeSet
| 27 | visit in liquibase.changelog.visitor.UpdateVisitor
| 58 | run . . . . . . . in liquibase.changelog.ChangeLogIterator
| 114 | update in liquibase.Liquibase
| 26 | doCall . . . . . in DbmUpdate$_run_closure1_closure2
| 59 | doCall in _DatabaseMigrationCommon_groovy$_run_closure2_closure11
| 133 | executeInSession in grails.plugin.databasemigration.MigrationUtils
| 51 | doCall in _DatabaseMigrationCommon_groovy$_run_closure2
^ 25 | doCall . . . . . in DbmUpdate$_run_closure1
Caused by MySQLIntegrityConstraintViolationException: Duplicate entry '' for key 'company_id'
->> 377 | handleNewInstance in com.mysql.jdbc.Util
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 360 | getInstance in ''
| 971 | createSQLException in com.mysql.jdbc.SQLError
| 3887 | checkErrorPacket in com.mysql.jdbc.MysqlIO
| 3823 | checkErrorPacket in ''
| 2435 | sendCommand in ''
| 2582 | sqlQueryDirect . in ''
| 2526 | execSQL in com.mysql.jdbc.ConnectionImpl
| 2484 | execSQL . . . . . in ''
| 848 | execute in com.mysql.jdbc.StatementImpl
| 742 | execute . . . . . in ''
| 92 | doInStatement in liquibase.executor.jvm.JdbcExecutor$1ExecuteStatementCallback
| 55 | execute . . . . . in liquibase.executor.jvm.JdbcExecutor
| 104 | execute in ''
| 1091 | execute . . . . . in liquibase.database.AbstractDatabase
| 1075 | executeStatements in ''
| 317 | execute . . . . . in liquibase.changelog.ChangeSet
| 27 | visit in liquibase.changelog.visitor.UpdateVisitor
| 58 | run . . . . . . . in liquibase.changelog.ChangeLogIterator
| 114 | update in liquibase.Liquibase
| 26 | doCall . . . . . in DbmUpdate$_run_closure1_closure2
| 59 | doCall in _DatabaseMigrationCommon_groovy$_run_closure2_closure11
| 133 | executeInSession in grails.plugin.databasemigration.MigrationUtils
| 51 | doCall in _DatabaseMigrationCommon_groovy$_run_closure2
^ 25 | doCall . . . . . in DbmUpdate$_run_closure1
liquibase.exception.MigrationFailedException: Migration failed for change set 2015-01-20-update-Company.groovy::1421762562430-2::mg (generated):
Reason: liquibase.exception.DatabaseException: Error executing SQL ALTER TABLE `sticker_group` ADD `company_id` VARCHAR(10) NOT NULL UNIQUE: Duplicate entry '' for key 'company_id':
Caused By: Error executing SQL ALTER TABLE `sticker_group` ADD `company_id` VARCHAR(10) NOT NULL UNIQUE: Duplicate entry '' for key 'company_id':
Caused By: Duplicate entry '' for key 'company_id'
at liquibase.changelog.ChangeSet.execute(ChangeSet.java:347)
at liquibase.changelog.visitor.UpdateVisitor.visit(UpdateVisitor.java:27)
at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:58)
at liquibase.Liquibase.update(Liquibase.java:114)
at DbmUpdate$_run_closure1_closure2.doCall(DbmUpdate:26)
at _DatabaseMigrationCommon_groovy$_run_closure2_closure11.doCall(_DatabaseMigrationCommon_groovy:59)
at grails.plugin.databasemigration.MigrationUtils.executeInSession(MigrationUtils.groovy:133)
at _DatabaseMigrationCommon_groovy$_run_closure2.doCall(_DatabaseMigrationCommon_groovy:51)
at DbmUpdate$_run_closure1.doCall(DbmUpdate:25)
Caused by: liquibase.exception.DatabaseException: Error executing SQL ALTER TABLE `sticker_group` ADD `company_id` VARCHAR(10) NOT NULL UNIQUE: Duplicate entry '' for key 'company_id'
at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:62)
at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:104)
at liquibase.database.AbstractDatabase.execute(AbstractDatabase.java:1091)
at liquibase.database.AbstractDatabase.executeStatements(AbstractDatabase.java:1075)
at liquibase.changelog.ChangeSet.execute(ChangeSet.java:317)
... 8 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '' for key 'company_id'
at com.mysql.jdbc.Util.handleNewInstance(Util.java:377)
at com.mysql.jdbc.Util.getInstance(Util.java:360)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:971)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3887)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3823)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2526)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2484)
at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:848)
at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:742)
at liquibase.executor.jvm.JdbcExecutor$1ExecuteStatementCallback.doInStatement(JdbcExecutor.java:92)
at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:55)
... 12 more
How can I fix this error?

Hive Table returning empty result set on all queries

I created a Hive Table, which loads data from a text file. But its returning empty result set on all queries.
I tried the following command:
CREATE TABLE table2(
id1 INT,
id2 INT,
id3 INT,
id4 STRING,
id5 INT,
id6 STRING,
id7 STRING,
id8 STRING,
id9 STRING,
id10 STRING,
id11 STRING,
id12 STRING,
id13 STRING,
id14 STRING,
id15 STRING
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '|'
STORED AS TEXTFILE
LOCATION '/user/biadmin/lineitem';
The command gets executed, and the table gets created. But, always returns 0 rows for all queries, including SELECT * FROM table2;
Sample data:
Single line of the input data:
1|155190|7706|1|17|21168.23|0.04|0.02|N|O|1996-03-13|1996-02-12|1996-03-22|DELIVER IN PERSON|TRUCK|egular courts above the|
I have attached the screen shot of the data file.
Output for command: DESCRIBE FORMATTED table2;
| Wed Apr 16 20:18:58 IST 2014 : Connection obtained for host: big-instght-15.persistent.co.in, port number 1528. |
| # col_name data_type comment |
| |
| id1 int None |
| id2 int None |
| id3 int None |
| id4 string None |
| id5 int None |
| id6 string None |
| id7 string None |
| id8 string None |
| id9 string None |
| id10 string None |
| id11 string None |
| id12 string None |
| id13 string None |
| id14 string None |
| id15 string None |
| |
| # Detailed Table Information |
| Database: default |
| Owner: biadmin |
| CreateTime: Mon Apr 14 20:17:31 IST 2014 |
| LastAccessTime: UNKNOWN |
| Protect Mode: None |
| Retention: 0 |
| Location: hdfs://big-instght-11.persistent.co.in:9000/user/biadmin/lineitem |
| Table Type: MANAGED_TABLE |
| Table Parameters: |
| serialization.null.format |
| transient_lastDdlTime 1397486851 |
| |
| # Storage Information |
| SerDe Library: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe |
| InputFormat: org.apache.hadoop.mapred.TextInputFormat |
| OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat |
| Compressed: No |
| Num Buckets: -1 |
| Bucket Columns: [] |
| Sort Columns: [] |
| Storage Desc Params: |
| field.delim | |
+-----------------------------------------------------------------------------------------------------------------+
Thanks!
Please make sure that the location /user/biadmin/lineitem.txt actually exists and you have data present there. Since you are using LOCATION clause your data must be present there, instead of the default warehouse location, /user/hive/warehouse.
Do a quick ls to verify that :
bin/hadoop fs -ls /user/biadmin/lineitem.txt
Also, make sure that you are using the proper delimiter.
Did you tried with LOAD DATA LOCAL INFILE
LOAD DATA LOCAL INFILE'/user/biadmin/lineitem.txt' INTO TABLE table2
FIELDS TERMINATED BY '|'
LINES TERMINATED BY '\n'
(id1,id2,id3........);
Documentation: http://dev.mysql.com/doc/refman/5.1/en/load-data.html
Are you using managed table or external table?? If it is external table you should use external keyword while creating the table. after creating the table load data into the table using load command. if it is managed table, after loading data to the table, you could see the data in your hive warehouse directory in hadoop. the default path is "/user/hive/warehouse/yourtablename".
you should run the load command in the hive shell.
I was able to load the data to the table. The problem was:
LOCATION '/user/biadmin/lineitem';
wasn't loading any data. But when I gave the directory containing the file as the path like:
LOCATION '/user/biadmin/tpc-h';
where I put the lineite.txt file in the tpc-h directory.
It worked!

How to tell Grails to render JSONNull as null?

I have a JSON object returned from Groovy's HTTPBuilder. THE JSON contains some null values represented as JSONNull objects. The problem is that when I try to render the JSON back in a response, I get an error when it tries to render the JSONNull. I get a response that is only partially rendered. I want it to render as "null". How do I do this?
Code:
render(contentType: "text/json") {
listOfJSONObjectsThatIncludeJSONNulls
}
Error:
| Error 2013-09-17 11:33:56,965 [http-bio-8080-exec-4] ERROR errors.GrailsExceptionResolver - JSONException occurred when processing request: [GET] /my/action
Object is null. Stacktrace follows:
Message: Object is null
Line | Method
->> 69 | isEmpty in net.sf.json.JSONNull
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 199 | value in grails.converters.JSON
| 162 | convertAnother in ''
| 199 | value in ''
| 162 | convertAnother in ''
| 199 | value in ''
| 162 | convertAnother in ''
| 199 | value in ''
| 162 | convertAnother in ''
| 199 | value in ''
| 162 | convertAnother in ''
| 199 | value in ''
| 162 | convertAnother in ''
| 199 | value in ''
| 134 | render . . . . in ''
| 150 | render in ''
| 63 | doCall . . . . in myproject.MyController$_index_closure1_closure2_closure4$$EOHirVeS
| 477 | doRequest in groovyx.net.http.HTTPBuilder
| 417 | doRequest . . in ''
| 349 | request in ''
| 43 | doCall . . . . in myproject.MyController$_index_closure1$$EOHirVeS
| 477 | doRequest in groovyx.net.http.HTTPBuilder
| 268 | get . . . . . in ''
| 31 | index in myproject.MyController$$EOHirVeS
| 895 | runTask . . . in java.util.concurrent.ThreadPoolExecutor$Worker
| 918 | run in ''
^ 680 | run . . . . . in java.lang.Thread
Partially Rendered Output:
[{"keyWithNullValue":{"array":false,"class":"net.sf.json.JSONNull"
I used the following code to render JSONNull as an empty string.
grails.converters.JSON.registerObjectMarshaller(JSONNull, { return "" })
I think you can fix it by specifying the below one in BootStrap
JSONObject.NULL.metaClass.asBoolean = {-> false}
Have a look at: how to get a real null value instead of a JSONObject.NULL value when parsing JSON in grails