Issue converting PostgreSQL query to DSLContext - java

I am trying to convert a query I wrote and tested from the command line to a DSLContext query using jOOq and am encountering issues. The query below is intended to return a list of tags that match the like parameter with a wildcard from a table "campaign" with a JSONB column "tags". This column has values formatted in the following way:
["dogs","cats","rabbits"]
select distinct A.value
from campaign T, LATERAL jsonb_array_elements_text(T.tags) A
where A.value LIKE 't%'
I am attempting to create this to a DSLContext in the following manner but I get an error "ERROR: argument of AND must not return a set". Can anyone see what I can do to resolve this issue and produce the same results from my PostgreSQL query and my DSL query below?
final Field<String> tagField = field("jsonb_array_elements_text(tags)", String.class);
final Table<Record1<String>> lateral =
lateral(sql.dsl().select(a).from(CAMPAIGN)).asTable();
final Result<Record1<String>> tag = sql.dsl()
.select(tagField)
.from(CAMPAIGN, lateral)
.where(tagField.like("t"))
.fetch();

Your query would translate to jOOQ as such:
Field<String> value = field(name("A", "value"), String.class);
sql.dsl()
.selectDistinct(value)
.from(
CAMPAIGN,
lateral(table("jsonb_array_elements_text({0})", CAMPAIGN.TAGS)).as("A"))
.where(value.like("t%"))
.fetch();

Related

Commons DBUtils Oracle 11.2.0.4 with Java 1.7 Binding parameters SQLException ORA-00942

I'm working with Oracle Database 11.2.0.4 with ojdbc6.jar, and I'm using apache commons dbutils v1.7, with JDK 7. So I'm using the QueryRunner and its method in this function
private <T> List<T> executeQueryAndReturnBeanList(String query, Class<T> className, Object... param) throws SQLException {
Connection connection = getDBConnectionInstance();
DbUtils.loadDriver("oracle.jdbc.driver.OracleDriver");
ResultSetHandler<List<T>> beanListHandler = new BeanListHandler<>(className,new BasicRowProcessor(new GenerousBeanProcessor()));
QueryRunner runner = new QueryRunner();
List<T> list = runner.query(connection, query, beanListHandler, param);
return list;
}
and everything works fine with select query without binding parameters
SELECT * FROM PEOPLE WHERE GRUPPO = 1 AND LANG = 'en_US'
But when I excute this query
String query = "SELECT * FROM PEOPLE WHERE GRUPPO = ? AND LANG = ?";
It gives me this SQL Exception
java.sql.SQLException: ORA-00942: table or view does not exist
Query: SELECT * FROM PEOPLE WHERE GRUPPO = ? AND LANG = ? Parameters: [1, en_US]
at org.apache.commons.dbutils.AbstractQueryRunner.rethrow(AbstractQueryRunner.java:527)
at org.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:391)
at org.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:252)
at mypackage.executeQueryAndReturnBeanList(JDBCFunctions.java:199)
I really don't know why. I tried to use :P1, :P2 or :1, :2 instead of ? to bind parameters but nothing it happens. Any ideas?
Group is a reserved word and cannot be used as a column or table name. Most probably you have a quoted column name such as "GROUP" within the table.
So, need to query as
SELECT * FROM PEOPLE WHERE "GROUP" = 1 AND LANG = 'en_US'
Quoted table names should be case sensitive, unlike unquoted ones.
The above one is the basic mistake, while the error(ORA-00942) suggests that your application connects to different schema than the schema in which successfully tested the query.
I finally found the solution. I inserted " on every column and table's name and now it works. For example:
String query = "SELECT * FROM \"PEOPLE\" WHERE \"GRUPPO\" = ? AND \"LANG\" = ?"

Pass the dynamically created query (according to condition) in #Query annotation

I am using the #Query annotation to execute the query in spring repository.
But I want to change the some part or make a new query according to the condition and pass in the #Query("pass here the query according to condition")
This is my query
#Query("SELECT ds.symptom FROM DoctorSymptomsModel ds where ds.doctorId = :doctorId and ds.isMostUsed = :isMostUsed)
If some condition satisfy then concat the "ORDER BY createdDate" part in query.
Or
Can I make the variable and set the query in that variable and set like that
String query = SELECT ds.symptom FROM DoctorSymptomsModel ds where
ds.doctorId = :doctorId and ds.isMostUsed = :isMostUsed
if(result){
query = SELECT ds.symptom FROM DoctorSymptomsModel ds where ds.doctorId =
:doctorId and ds.isMostUsed = :isMostUsed ORDER BY createdDate
}
//pass the query variable here
#Query(query)
List<String> findDoctorSymptomsModelList(#Param("doctorId") long doctorId,
#Param("isMostUsed") boolean isMostUsed);
To make a dynamic query, you should think about CriteriaQuery. Take a look at this link for brief introduction.

How does a native sql query bind fields to an entity instead of map

I tried to run native sql query with resulttransformer (AliasToBeanResultTransformer), it gives error like below.
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: com.ozpas.ozentegre.entity.EntDevirlog cannot be cast to java.util.Map
at org.hibernate.property.access.internal.PropertyAccessMapImpl$SetterImpl.set(PropertyAccessMapImpl.java:102)
at org.hibernate.transform.AliasToBeanResultTransformer.transformTuple(AliasToBeanResultTransformer.java:78)
By the way, my native sql query does not include all fields in the entity ( EntDevirlog ), there are only some fields in that entity. shall the query include all fields in the entity ?
as i understood, hibernate transforms result into a map object instead EntDevirlog entity. It uses PropertyAccessMapImpl. how can i solve this problem to get the result as a list ( arraylist ) ? thanks.
Session session = HibernateUtilMikro.getSessionFactory().openSession();
List<EntDevirlog> results = new ArrayList<EntDevirlog>();
Transaction tx = null;
String sql = "mynativequery";
SQLQuery query = session.createSQLQuery(sql);
query.setParameter("tarih", tarih);
query.setParameter("srmkodu", srmkodu);
query.setParameter("s1", EnumPanoislemtipleri.islem1.getValue());
query.setParameter("s2", EnumPanoislemtipleri.islem2.getValue());
query.setResultTransformer(new AliasToBeanResultTransformer(EntDevirlog.class));
results = query.list();
tx.commit();
Just use the quotes for the aliases
"select firstName as \"firstName\",
lastName as \"lastName\" from Employee"
Read for a more deeply explanation here:
mapping Hibernate query results to custom class?

How to use net.java.ao.Query to query issues?

I have this select in PostgreSQL:
SELECT "field_1", "field_2","field_3", MIN(COALESCE(NULLIF("field_4",'') ,'TBD')) MINDP,MIN("field_5") MINBOD FROM "MY_TABLE" GROUP BY "field_1", "field_2","field_3"
And I want to use net.java.ao.Query to query my database. My function:
import net.java.ao.Query;
public List<myClass> find() {
String SQL = "SELECT \"field_1\", \"field_2\",\"field_3\", MIN(COALESCE(NULLIF(\"field_4\",'') ,'TBD')) MINDP,MIN(\"field_5\") MINBOD FROM \"MY_TABLE\" GROUP BY \"field_1\", \"field_2\",\"field_3\""
return newArrayList(ao.find(myClass.class, Query.select(SQL)));
}
The problem is: this code return all issues of my table.
When I run this SQL in postgreSQL console it works fine.
My code has different results than SQL console.
Does anybody know why is this happening?
Old question but if somebody steps over this -
Query.select() is not meant to put plain SQL into. It is more of a builder to create 'database independant' query. See some examples here: Finding entities
public MyEntity[] findMyEntities(String fieldValue) {
final Query query = Query.select()
.where("FIELD_VALUE = ?", fieldValue);
// evaluates to something like this
// SELECT * FROM MY_ENTITY WHERE FIELD_VALUE = x;
return ao.find(MyEntity.class, query);
}
This is why there's another method (which you used in your comment), that can handle plain SQL (findWithSQL).
Attention Query and find() often do not work as expected, so you might not get your original query to work using the query builder.

Order by attribute of foreign entity in ORMLite

How can I build a query in ORMLite so that I can use the orderBy function (using either the one with the raw string or the parametrized one) referencing an attribute of a different entity than the one of the dao I'm building the query from? My query is built like that:
// Inner query for performances
QueryBuilder<Performance, String> performancesQB = performanceDao.queryBuilder();
performancesQB.selectColumns("performance_id");
SelectArg performanceSelectArg = new SelectArg();
performancesQB.where().lt("date", performanceSelectArg);
// Outer query for Order objects, where the id matches in the performance_id
// from the inner query
QueryBuilder<Order, String> ordersQB = orderDao.queryBuilder();
ordersQB.where().isNull("user_id").and().in("performance_id", performancesQB);
ordersQB.orderByRaw("performances.date DESC");
pastOrdersQuery = ordersQB.prepare();
And the exception I'm getting whenever I try to execute this query is:
android.database.sqlite.SQLiteException: no such column: performances.date:,
while compiling: SELECT * FROM `orders` WHERE
(`user_id` IS NULL AND `performance_id` IN
(SELECT `performance_id` FROM `performances` WHERE `date` < ? ) )
ORDER BY performances.date DESC
The only solution I see here is writing a raw query myself using a JOIN instead of a nested select. May this be a good solution?
ORMLite now supports simple JOIN queries. Here the docs on the subject:
http://ormlite.com/docs/join-queries
So your query would now look something like:
QueryBuilder<Performance, String> performancesQB = performanceDao.queryBuilder();
SelectArg performanceSelectArg = new SelectArg();
performancesQB.where().lt("date", performanceSelectArg);
performancesQB.orderBy("date", false);
// query for Order objects, where the id matches
QueryBuilder<Order, String> ordersQB = orderDao.queryBuilder();
ordersQB.join(performancesQB).where().isNull("user_id");
pastOrdersQuery = ordersQB.prepare();

Categories