Using SQLExpression from QueryDsl - java

I want to use the SQLExpressions from QueryDsl. I have a Q-object called qMyClass. Now I want to use the listagg function of the oracle database. Therefore i want to initialize a WithinGroup-object.
WithinGroup<Object>.OrderBy withinGroup = SQLExpressions.listagg(qMyClass.attributeName, "/").withinGroup().orderBy(qMyClass.attributeName);
The first part
SQLExpressions.listagg(qMyClass.attributeName, "/")
already gives me the error:
unknown operation with operator LISTAGG and args
[myClass.attributeName, /]
Does anyone know how to use listagg? Didn't find any helpful information on the web. I am using version 4.0.2 of QueryDsl. Thanks!

Try something like this:
select(
qMyClass.id,
SQLExpressions.listagg(qMyClass.attributeName,"/")
.withinGroup()
.orderBy(qMyClass.attributeName.asc())
.getValue()
.as("foo"))
.from(qMyClass)
.groupBy(qMyClass.id);

Related

Jooq update return value

I try to update rows in table and get results after.
If I do
dsl.update(TABLE)
.set(TABLE.ROW, newRow)
.where(TABLE.ROW_2.eq(
dsl.select(ANOTHER_TABLE.ID)
.from(ANOTHER_TABLE)
.where(ANOTHER_TABLE.GUID.eq(guid))
)).execute()
it returns 1. But if I do
dsl.update(TABLE)
.set(TABLE.ROW, newRow)
.where(TABLE.ROW_2.eq(
dsl.select(ANOTHER_TABLE.ID)
.from(ANOTHER_TABLE)
.where(ANOTHER_TABLE.GUID.eq(guid))
)).returningResult(TABLE.ROW_3).fetchOne()
it returns empty result. But I want to get TABLE.ROW_3 after update. Whats the problem?
Vertica doesn't support UPDATE .. RETURNING like PostgreSQL, as can be seen in the Vertica docs:
https://www.vertica.com/docs/9.2.x/HTML/Content/Authoring/SQLReferenceManual/Statements/UPDATE.htm
The jOOQ documentation of UpdateReturningStep::returningResult reflects this by not listing SQLDialect.VERTICA in its #Support annotation:
#Support({AURORA_POSTGRES,COCKROACHDB,DB2,FIREBIRD,ORACLE,POSTGRES,SQLSERVER})
There's currently no workaround for this. If you want to avoid using such API, you could use the jOOQ-checker module in your build to produce compilation errors whenever you use API that is not supported by VERTICA

using $addToset with java morphia aggregation

I have mongodb aggregation query and it works perfectly in shell.
How can i rewrite this query to use with morphia ?
org.mongodb.morphia.aggregation.Group.addToSet(String field) accepts only one field name but i need to add object to the set.
Query:
......aggregate([
{$group:
{"_id":"$subjectHash",
"authors":{$addToSet:"$fromAddress.address"},
---->> "messageDataSet":{$addToSet:{"sentDate":"$sentDate","messageId":"$_id"}},
"messageCount":{$sum:1}}},
{$sort:{....}},
{$limit:10},
{$skip:0}
])
Java code:
AggregationPipeline aggregationPipeline = myDatastore.createAggregation(Message.class)
.group("subjectHash",
grouping("authors", addToSet("fromAddress.address")),
--------??????------>> grouping("messageDataSet", ???????),
grouping("messageCount", new Accumulator("$sum", 1))
).sort(...)).limit(...).skip(...);
That's currently not supported but if you'll file an issue I'd be happy to include that in an upcoming release.
Thanks for your answer, I can guess that according to source code. :(
I don't want to use spring-data or java-driver directly (for this project) so I changed my document representation.
Added messageDataSet object which contains sentDate and messageId (and some other nested objects) (these values become duplicated in a document which is a bad design).
Aggregation becomes : "messageDataSet":{$addToSet:"$messageDataSet"},
and Java code is: grouping("messageDataSet", addToSet("messageDataSet")),
This works with moprhia. Thanks.

IntelliJ IDEA code inspection: HQL custom dialect & registered functions

My question is about
using registered functions for date/time manipulations in Hibernate Query Language and
IntelliJ IDEA's code inspection for these registered functions in HQL.
I'm using Hibernate 4.2.5 with Java 7, and SQL Server 2008 R2 as the database, and IntelliJ IDEA 12.1.6.
In an HQL query I need to perform the TSQL DATEADD function - or the equivalent HQL date operation. This doesn't seem to exist.
Here's what I'd like to achieve:
update MyTable set startTime = GETDATE(), targetTime = DATEADD(HOUR, allocatedTime, GETDATE()), endTime = null where faultReport.faultReportId = :faultReportId and slaTypeId = :slaTypeId
Searching for answers online has been disappointingly no help, and the most common advice (like the comment seen here: https://stackoverflow.com/a/18150333/2753571) seems to be "don't use date manipulation in hql." I don't see how I can get around performing the operation in the SQL statement in the general case (e.g. when you want to update one column based on the value in another column in multiple rows).
In a similar fashion to the advice in this post: Date operations in HQL, I've subclassed a SQLServerDialect implementation and registered new functions:
registerFunction("get_date", new NoArgSQLFunction("GETDATE", StandardBasicTypes.TIMESTAMP)); // this function is a duplication of "current_timestamp" but is here for testing / illustration
registerFunction("add_hours", new VarArgsSQLFunction(TimestampType.INSTANCE, "DATEADD(HOUR,", ",", ")"));
and added this property to my persistence.xml:
<property name="hibernate.dialect" value="my.project.dialect.SqlServerDialectExtended" />
and then I'm testing with a simple (meaningless, admitted) query like this:
select x, get_date(), add_hours(1, get_date()) from MyTable x
The functions appear to be successfully registered, and that query seems to be working because the following SQL is generated and the results are correct:
select
faultrepor0_.FaultReportSLATrackingId as col_0_0_,
GETDATE() as col_1_0_,
DATEADD(HOUR,
1,
GETDATE()) as col_2_0_,
... etc.
But I now have this problem with IntelliJ IDEA: where get_date() is used in the HQL, the code inspection complains "<expression> expected, got ')'". This is marked as an error and the file is marked in red as a compilation failure.
Can someone can explain how to deal with this, please, or explain what a better approach is? Am I using the incorrect SQLFunction template (VarArgsSQLFunction)? If yes, which is the best one to use?
I'd like the usage of the registered function to not be marked as invalid in my IDE. Ideally, if someone can suggest a better way altogether than creating a new dialect subclass, that would be awesome.

Convert SQL Query to play Query Builder Syntax

I need help with converting an SQL-Query to something I can use inside play!
The original Query looks like this:
SELECT * FROM `triplestore`
WHERE `owning_admin_id` IS NOT NULL
AND `is_public` IS true;
My goal is to get something like
Triplestore.find.where()
.isNotNull("owningAdmin")
.is("is_public", true)
.findList();
Is this even possible or do I have to use JPQL? What would that Query look like?
Thanks in advance,
Hagen
You can use the and() method:
Triplestore.find.where().and(Expr.isNotNull("owningAdmin"),Expr.eq("is_public", true)).findList();
Don't forget to add the com.avaje.ebean.Expr import.
In Hibernate Criteria:
List<Triplestore> triplestores =
(List<Triplestore>) session.createCriteria(Triplestore.class)
.add( Restrictions.isNotNull("owning_admin_id") )
.add( Restrictions.eq("is_public", Boolean.TRUE) ).list();
Regards,
You said "something I can use inside play!", so I'm assuming any third party library is OK. Here's a solution using jOOQ (disclaimer: I work for the vendor).
I'm assuming you're using jOOQ's code generator here:
Result<TriplestoreRecord> result =
ctx.selectFrom(TRIPLESTORE)
.where(TRIPLESTORE.OWNING_ADMIN_ID.isNotNull())
.and(TRIPLESTORE.IS_PUBLIC)
.fetch();

OJB / Oracle XE sql debug-display problem

I have a Java application, and use OJB as my ORM technology. I have an Oracle XE installation locally to develop against. The problem is when I need to debug a problem, I like looking at the SQL output. Here is an example of SQL I can view through the "Top SQL" interface in Oracle XE:
select a_bunch_of_fields
from KREW_DOC_TYP_T A0
WHERE ((UPPER(A0.DOC_TYP_NM) LIKE :1) AND A0.ACTV_IND = :2) AND A0.CUR_IND = :3
The problem is I would like to see the real value instead of ":1". I can't seem to find how I can configure this. I know the real values are working, because the application is responding as expected, for the most part (hence the bugs I am working on).
Thanks,
Jay
One quick and dirty way is to look in the provided database views (v$sql_bind_capture and v$sqlarea). In the SQL below, I just added a like clause to match the sql statement you have above, you will then get a row for each bind variable and it's value. To target a very specific SQL statement you want the sql_id for your query.
SELECT a.sql_text, b.NAME, b.POSITION, b.datatype_string, b.value_string
FROM v$sql_bind_capture b, v$sqlarea b
WHERE b.sql_id = a.sql_id
and a.sql_text like '%UPPER(A0.DOC_TYP_NM) LIKE :1%'
Output (without the SQL the result would look look something like this):
"NAME","POSITION","DATATYPE_STRING","VALUE_STRING"
":B1","2","NUMBER","1001"

Categories

Resources