Spring CriteriaBuilder query JSONArray data - mysql

I have used a table for storing JSON data. For a specific client I create records for 12 months and store the data of the 12 months in JSONArray format. In that way I create one row per client.
The approved field can be true, false or null. What I need to do is, check whether the approved value is true and that the data is not null. I tried to search for queries JSON data but couldn't find solution.
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<ClientData> clientQuery = cb.createQuery(ClientData.class);
Root<ClientData> clientMaster = clientQuery.from(ClientData.class);
..
..
..
predicates.add(cb.isTrue(cb.function("json_contains", Boolean.class,
clientMaster.get("Data"), cb.literal("approved"))));
predicates.add(cb.isNotNull(cb.function("json_contains", Double.class,
clientMaster.get("Data"), cb.literal("data"))));
But this gave me error:-
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Invalid JSON text in argument 2 to function json_contains: "Invalid value." at position 1.
I'm using MySQL version 5.7.31. Any help would be appreciated.

try this way
if(!CommonUtils.checkIsNullOrEmpty(filterDto.getProduct()) ) {
String a=(String.join(",",filterDto.getProduct()));
predicates.add(cb.isTrue(cb.function("json_contains", Boolean.class,
userRoot.get("product"), cb.literal("\"" + a + "\""))));
// predicates.add(userRoot.get("product").in(a));
}

Related

How to INSERT JSON objects in an array in MySQL?

I am currently assigned to a task to transform our active non-normalized table to a normalized one. We decided to use database triggers to facilitate the bulk migration and succeeding data changes until we discontinue the old table.
Below are the structure and sample of our old table:
SELECT * FROM TabHmIds;
ID EntitlementID TabId HmId
1 101 201 301
2 102 202 302
The required structure and sample of our new table should look like:
SELECT * FROM tab_integration;
id tab_id integration_id metadata
1 201 1 { "paid_id": {"entitlement_id": 101, "id": 301} }
2 202 1 { "paid_id": {"entitlement_id": 202, "id": 302} }
The following is what I have done in my INSERT trigger so far:
CREATE TRIGGER tab_integration_after_insert AFTER INSERT ON `TabHmIds`
FOR EACH ROW
BEGIN
DECLARE var_metadata JSON;
DECLARE var_new_metadata JSON;
DECLARE var_hm_metadata JSON;
DECLARE var_integration_id INT(11);
SELECT
metadata,
integration_id INTO var_metadata,
var_integration_id
FROM
`go`.`tab_integration` gti
WHERE
gti.`tab_id` = NEW.`TabId`;
SET var_hm_metadata = JSON_OBJECT('entitlement_id', NEW.`EntitlementId`, 'id', NEW.`HmId`);
IF var_integration_id = 1 THEN
IF var_metadata IS NULL THEN
SET var_new_metadata = JSON_OBJECT('paid_id', var_hm_metadata);
ELSE
SET #paid_id = JSON_UNQUOTE(JSON_EXTRACT(var_metadata, '$.paid_id'));
SET var_new_metadata = JSON_ARRAY_APPEND(var_metadata, '$.paid_id', var_hm_metadata);
END IF;
END IF;
UPDATE `tab_integration` gti SET `metadata` = var_new_metadata WHERE `tab_id` = NEW.`TabId`;
END
However, what I get is this:
SELECT * FROM tab_integration;
id tab_id integration_id metadata
1 201 1 { "paid_id": "{\"entitlement_id\": 101, \"id\": 301}" }
2 202 1 { "paid_id": "{\"entitlement_id\": 202, \"id\": 302}" }
From the table above, the JSON object is parsed into STRING. I am aware that the JSON_OBJECT parses the passed value to a string. SO I used the JSON_UNQUOTE(JSON_EXTRACT(…)) to convert the paid_id path value to JSON, but it does not get parsed into JSON. I also tried JSON_MERGE_PRESERVE to put the JSON object under the paid_id path but I end up getting:
{“paid_id”: [], “entitlement_id”: 101, “id”: 301 }
I also tried to put the JSON array into a temporary table using JSON_TABLE and modify the values in the temporary and convert that temporary table to JSON using JSONARRAYAGG. But Workbench keeps saying I have an error in my syntax even though I directly copied examples from the web.
I also tried CASTing a well-formed string to JSON, but Workbench also throws a syntax error.
I have spent a week into resolving this data structure in MySQL.
Database scripting is not my strong suit and I am new to the JSON functions in MySQL. Thank you in advance to those who will reply.
If in case needed, my MySQL Workbench is version 10.4.13-MariaDB. But the script should work in MySQL 5.7.
I found the answer to my problem.
Before inserting the new JSON data, I parsed it to CHAR and REPLACEd the characters making it a string. I did the following and it worked!
# After performing the needed JSON manipulations, cleanse the JSON string to JSON.
SET var_new_metadata = CAST(var_new_metadata AS CHAR);
SELECT REPLACE(REPLACE(REPLACE(var_new_metadata, '\\', ''), '\"\{', '{'), '\}\"', '}') INTO var_new_metadata;
After cleansing the data, the UPDATE call still worked and tried to do some JSON manipulations after and, yes, still works!

Why 'JSON_LENGTH' function always return 1 result when I query the a jsonArray String in mysql?

everyone.
There a json type column (e.g registered_result) on mysql,and saved json string ,such as:
http://regjl.cn:8080/json.txt
(I cant put in there ,because will give me Body cannot contain "".)
I try use these sql to get The JsonArray length:
SELECT JSON_LENGTH(registered_result) FROM query_record WHERE XXX
But It always return 1 result ( in fact is 10)? where the problem is ?

Insert data into JSON column in postgres using JOOQ

I have a postgres database to which I read/write using JOOQ. One of my DB tables has a column of type JSON. When I try to insert data into this column using the query below, I get the error
Exception in thread "main" org.jooq.exception.DataAccessException: SQL [update "public"."asset_state" set "sites_as_json" = ?]; ERROR: column "sites_as_json" is of type json but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Below is the code for inserting data into the column
SiteObj s1 = new SiteObj();
s1.setId("1");
s1.setName("Site1");
s1.setGeofenceType("Customer Site");
SiteObj s2 = new SiteObj();
s2.setId("2");
s2.setName("Site2");
s2.setGeofenceType("Customer Site");
List<SiteObj> sitesList = Arrays.asList(s1, s2);
int result = this.dsl.update(as).set(as.SITES_AS_JSON, LambdaUtil.convertJsonToStr(sitesList)).execute();
The call LambdaUtil.convertJsonToStr(sitesList) outputs a string that looks like this...
[{"id":"1","name":"Site1","geofenceType":"Customer Site"},{"id":"2","name":"Site2","geofenceType":"Customer Site"}]
What do I need to do to be able to insert into the JSON column?
Current jOOQ versions
jOOQ natively supports JSON and JSONB data types. You shouldn't need to have to do anything custom.
Historic answer
For jOOQ to correctly bind your JSON string to the JDBC driver, you will need to implement a data type binding as documented here:
https://www.jooq.org/doc/latest/manual/code-generation/custom-data-type-bindings
The important bit is the fact that your generated SQL needs to produce an explicit type cast, for example:
#Override
public void sql(BindingSQLContext<JsonElement> ctx) throws SQLException {
// Depending on how you generate your SQL, you may need to explicitly distinguish
// between jOOQ generating bind variables or inlined literals.
if (ctx.render().paramType() == ParamType.INLINED)
ctx.render().visit(DSL.inline(ctx.convert(converter()).value())).sql("::json");
else
ctx.render().sql("?::json");
}

Capture any standard report to JSON or XML?

I know that I can use LIST_TO_ASCI to convert a report to ASCII, but I would like to have a more high level data format like JSON, XML, CSV.
Is there a way to get something that is easier to handle then ASCII?
Here is the report I'd like to convert:
The conversion needs to be executed in ABAP on a result which was executed like this:
SUBMIT <REPORT_NAME> ... EXPORTING LIST TO MEMORY AND RETURN.
You can get access to SUBMIT list in memory like this:
call function 'LIST_FROM_MEMORY'
TABLES
listobject = t_list
EXCEPTIONS
not_found = 1
others = 2.
if sy-subrc <> 0.
message 'Unable to get list from memory' type 'E'.
endif.
call function 'WRITE_LIST'
TABLES
listobject = t_list
EXCEPTIONS
EMPTY_LIST = 1
OTHERS = 2
.
if sy-subrc <> 0.
message 'Unable to write list' type 'E'.
endif.
And the final step of the solution (conversion of result table to JSON) was already answered to you in your question.
I found a solution here: http://zevolving.com/2015/07/salv-table-22-get-data-directly-after-submit/
This is the code:
DATA: lt_outtab TYPE STANDARD TABLE OF alv_t_t2.
FIELD-SYMBOLS: <lt_outtab> like lt_outtab.
DATA lo_data TYPE REF TO data.
" Let know the model
cl_salv_bs_runtime_info=>set(
EXPORTING
display = abap_false
metadata = abap_false
data = abap_true
).
SUBMIT salv_demo_table_simple
AND RETURN.
TRY.
" get data from SALV model
cl_salv_bs_runtime_info=>get_data_ref(
IMPORTING
r_data = lo_data
).
ASSIGN lo_data->* to <lt_outtab>.
BREAK-POINT.
CATCH cx_salv_bs_sc_runtime_info.
ENDTRY.
Big thanks to Sandra Rossi, she gave me the hint to cx_salv_bs_sc_runtime_info.
Related answer: https://stackoverflow.com/a/52834118/633961

Append a string value to an exisiting json value in mysql

I'm new to MySQL. I'm trying to add a string value to a json value in MySQL. The column name is IPConfig. This is the current json string in the column.
{"theme":"black", "button1link":"http//sample.com", "name":"pp"}
I have to append a "www" to button1link value.
Thanks in advance!
Here you can try
UPDATE table SET DATA= JSON_SET(DATA, "$.button1link", INSERT("http//sample.com", 7, 0,'www')) WHERE 1 = 1;
But for this to work, you will need MySQL 5.7+
You can have insert function docs here.