I have the following query which runs perfectly in mysql.
SELECT * FROM Orders as o, Products as p where o.productinfo RLIKE p.code;
Here I am joining two tables Orders and Products with RLIKE.
I am trying to implement the same in Hibernate.
Query query = session.createQuery("FROM Orders as o, Products as p where o.productinfo RLIKE p.code");
List<Object[]> results = query.getResultList();
When I used RLIKE, the following error is thrown in run time.
{"errormessage":"org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: RLIKE
I tried to implement the same with LIKE query and matched it with '%p.code%'.
Query query = session.createQuery("FROM Orders as o, Products as p where o.productinfo LIKE '%p.code%'");
But it matches with the string "p.code" rather then the value.
What is the equivalent of RLIKE in HQL?
Is there a different way to join two tables with LIKE in HQL?
Thanks.
Answer by #YCF_L:
For any one trying to join two tables with like operator in Hibernate (mysql) can do it the following way.
SELECT * FROM Orders as o, Products as p where o.productinfo LIKE CONCAT('%',p.code,'%');
What's the equivalent of mysql RLIKE operator in Hibernate Query?
RLIKE is the synonym for REGEXP so you can implement it in hibernate using REGEXP_LIKE, you can take a look about this here : How to search in multiple columns using one like operator in HQL (hibernate sql)
I tried to implement the same with LIKE query and matched it with
'%p.code%'.
..., Products as p where o.productinfo LIKE '%p.code%'");
But it matches with the string "p.code" rather then the value.
This is true, because you don't pass the correct value of p.code, you pass it like a String, instead you have two ways :
Query query = session.createQuery("....Products as p where o.productinfo LIKE '%:code%'");
//------------------------------------------------------------------------------^^^^^^^
query.setParameter("code", p.code);
Or you can concatenate your code with your Query, but the first solution is better.
Query query = session.createQuery(".... where o.productinfo LIKE '%" + p.code + "%'");
EDIT
You can use like with CONCAT without specify the '' like this :
SELECT * FROM Orders as o, Products as p where o.productinfo LIKE CONCAT('%',p.code,'%');
You can check regular expression way something like this way: Restrictions.sqlRestriction(word REGEXP '^[A-Z][A-Za-z]*$')
Please check the link which will be helpful for this case: Regular expression with criteria
Related
I have a query like below:
select * from Products p where ? between p.effctDate and p.expDate
Can I translate the above query to a spring data jpa query method? Like for example:
findByProductId(productId)
or I only have to use #Query or a Named query to handle such types of queries. I tried searching here first before asking the question as well as spring data site but did not find any solution. any help is appreciated.
You could use the following query:
Date date = //Input date
List<Product> = findByEffctDateAfterAndExpDateBefore(date, date);
Note that you have to enter date twice to match both 'where' clauses. This is under the assumption you are using Date objects, not literal Strings.
See JPA Repositories Table 2.3 for more info.
You can try to use something like below :
List findAllByDateApprovedBetween(String dateApprovedFrom, String dateApprovedTo);
It translates to :
Hibernate: select applicatio0_.id as id1_1_, applicatio0_.date_approved as date_app4_1_ from application applicatio0_ where (applicatio0_.date_approved between ? and ?)
You can try something like this trick:
select
p
from
Product p
where
(?1 = 'field1' and p.field1 between p.effctDate and p.expDate)
or (?1 = 'field2' and p.field2 between p.effctDate and p.expDate)
or (?1 = 'field3' and p.field3 between p.effctDate and p.expDate)
or (?1 = 'field4' and p.field4 between p.effctDate and p.expDate)
...
But this is not the best approach IMO...
To build dynamic queries you can use thees ones:
Specifications
Query by Example
Querydsl Extension
I'm trying to implement a query like this:
SELECT DISTINCT C.* FROM A
join B on A.some_id = B.some_id
join C on B.some_id = C.some_id;
With Hibernate Criteria API.
I need to have distinct results for whole C table, not just for some column(s) of it.
I tried to do like that:
Criteria criteria = createCriteria(C.class, "ct")
.createCriteria("B", "bt")
.createCriteria("A", "at")
.//Some restrictions which are applied to all tables
And like that:
Criteria criteria = createCriteria(A.class, "at")
.createCriteria("B", "bt")
.createCriteria("C", "ct")
.//Some restrictions which are applied to all tables
(I don't see a difference though).
Tried to ad ResultTransformer:
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
Tried to put all colums into ProjectionsList and then:
criteria.setProjection(Projections.distinct(projectionList));
But that projection only adds "distinct" keyword to first column in list but not to whole table.
What I want to achieve - is something like that:
criteria.setProjection(Projections.distinct("C.*"));
but I only can add a column here, can't use wildcards like in query.
Any help is greatly appreciated.
You should select columns from table 'C' not from table 'A' like below.
SELECT distinct (*) FROM C
it can be written in hibernate criteria as follows:
Criteria criteria = session.createCriteria(C.class);
criteria = criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
ResultTransformer rt = new DistinctRootEntityResultTransformer();
List list = rt.transformList(criteria.list());
I have a query, represented by a string:
final String q = "select 1 union select 2 union select 3";
This string comes from an external source (configuration), hence it is a string. In the real scenario, the query is ofcourse more meaningful.
I would like to execute this query as a subquery within a jOOQ type-safe query. The following works, but it is not really what I want:
System.out.println(<context>.select().from(DSL.table("person")).where(DSL.field("identifier").in(
<context>.fetch(q).intoArray(0)
)).fetch());
The problem here is that I am essentially executing two queries. This introduces overhead.
Is it possible to execute the string-query as a real subquery? I somehow have to convert the string-query to a Select<Record1> instance (I guess), but I cannot find how to do that.
There are a variety of places where you can inject a Select type as plain SQL. For instance:
As a plain SQL WHERE clause:
<context>.select()
.from(DSL.table("person"))
.where(
"identifier in ({0})", DSL.resultQuery(q)
)
.fetch();
As a plain SQL Table:
<context>.select()
.from(DSL.table("person"))
.where(DSL.field("identifier").in(
DSL.select().from("(" + q + ")")
))
.fetch();
There are others. The important thing to notice is that by using plain SQL, you have the possibility to embed your own SQL strings in templates that have enumerated placeholders
... {0} ... {1} ...
I'm building a select that has to get me all distinct values from a table.
The sql I would normally write would look like this: "SELECT DISTINCT ARTIST FROM MUSICLIB"
However, ebean is generating the following: "SELECT DISTINCT ID, ARTIST FROM MUSICLIB"
The finder is as such:
find.select("artist").setDistinct(true).findList();
I've found that ebean is generating this ID on every single query, no matter what options I set.
How do I accomplish what I'm looking for?
You can't do that, Ebean for objects mapping requires ID field, and if you won't include it you'll get some mysterious exceptions.
Instead you can query DB without mapping and then write your SQL statement yourself:
SqlQuery sqlQuery = Ebean.createSqlQuery("SELECT DISTINCT artist FROM musiclib");
List<SqlRow> rows = sqlQuery.findList();
for (SqlRow row : rows) {
debug("I got one: " + row.getString("artist"));
}
Of course if artist is a relation, you need to perform additional query using list of found IDs with in(...) expression.
I need to use the LIKE operator into an JPA query. I need to use it for types other then String but the JPA criteria API allows me to add only String parameters. I tried using the .as(String.class) but something fails and also tried calling the CAST function from the underlying Oracle that again fails for unknown reasons to me.
I tried writing the query also in JPQL and it works as expected. This is the query:
SELECT p from CustomerOrder p where p.id like '%62%'
UPDATE:
The query must be built in a generic fashion as it is for filtering, so it needs to be created at runtime. On the query that is already created I tried to add the LIKE clause like this:
query.where(builder.like(selectAttributePath.as(String.class), "%"+filterValue.toString().toLowerCase()+"%"));
But this crashes with this exception:
org.hibernate.hql.internal.ast.QuerySyntaxException: expecting CLOSE, found '(' near line 1, column 156 [select distinct generatedAlias0.id from de.brueckner.mms.proddetailschedact.data.CustomerOrder as generatedAlias0 where cast(generatedAlias0.id as varchar2(255 char)) like :param0]
I executed the same query directly to Oracle using SQLDeveloper, so it should be sound from this point of view. So the problem is the Hibernate is the issue. Any suggestions on how to fix it?
How can I write this query using JPA Criteria?
I fixed the problem by invoking the 'TO_CHAR' function from the underlying Oracle DB and using the LIKE operator like for normal String's.
query.where(builder.like(selectAttributePath.as(String.class), "%" +filterValue.toString().toLowerCase() + "%")
You can try the below code, it might require modifications.
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<CustomerOrder> cq = cb.createQuery(CustomerOrder.class);
Root<CustomerOrder> order = cq.from(CustomerOrder.class);
cq.where(cb.like(Long.valueOf(order.get(CustomerOrder_.id)).toString(), "%62%"));
TypedQuery<CustomerOrder> q = em.createQuery(cq);
List<CustomerOrder> results = q.getResultList();