Convert query Oracle with HQL (Hibernate Query Language) - java

I have this query for Oracle and i must convert in HQL (Hibernate Query Language). I haven't found information on convert key words like "START WITH" or "CONNECT BY PRIOR" or "SINBLINGS".
can you help me ?
The Query is this:
SELECT NOME_PADRE, COD_PADRE, NOME_FIGLIO, COD_FIGLIO,
CONFIRM_COD_FIGLIO, LEVEL
FROM (
SELECT s1.NOME AS NOME_PADRE, a.PADRE AS COD_PADRE, s2.NOME AS
NOME_FIGLIO, a.CMU AS COD_FIGLIO, s2.CMU AS
CONFIRM_COD_FIGLIO
FROM ALBERO a JOIN STRUTTURE s1 ON a.PADRE = s1.CMU
JOIN STRUTTURE s2 ON a.CMU = s2.CMU
ORDER BY PADRE ASC
)
START WITH COD_PADRE = '00000'
CONNECT BY PRIOR COD_FIGLIO = COD_PADRE
ORDER SIBLINGS BY COD_PADRE
Thank you very much

I tried to use a native query.
I use Spring-Boot and i have a Controller, a Service and a Repository.
In my repository, I implement a native query like this:
String QUERY = " SELECT s.CMU, s.NOME, a.PADRE, LEVEL "
+ " FROM STRUTTURE s LEFT JOIN ALBERO a ON s.CMU = a.CMU "
+ " START WITH a.PADRE = '00000' "
+ " CONNECT BY PRIOR a.CMU = a.PADRE "
+ " ORDER SIBLINGS BY a.PADRE";
#Query(nativeQuery = true, value = QUERY)
public List<Struttura> findAllWithConnectBy();
but I have this error:
org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'strutturaController': Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)

Related

ConverterNotFoundException only in Testing time

I have java spring (v2.7.1) application and I want to test my database (H2 DB) layer.
I have the following query:
#Query(value =
"SELECT something.c1 " +
"FROM " +
"(SELECT Count(c1) AS Count, c1 " +
"FROM Table1 " +
"WHERE c2 IN (:thing2Ids) " +
"GROUP BY c1) " +
"AS something " +
"WHERE something.Count = :thingCount",
nativeQuery = true)
List<UUID> findThings(#Param("thingCount") Integer thingCount, #Param("thing2Ids") List<String> thing2Ids);
At the end of my query I want to get back a list of UUIDs. When I run this query (i.e. I build and run the application and call this method) it is working fine. But when I try to test this, I got the following error:
org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.util.ArrayList<?>] to type [#org.springframework.data.jpa.repository.Query java.util.List<java.util.UUID>] for value '[[somevalue1, [somevalue2]'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [byte[]] to type [#org.springframework.data.jpa.repository.Query java.util.UUID]
Why my code needs converter at testing time but runtim don't? I don't get the point here.
I have checked this, this articles already but I don't want to write a converter just because of testing my app. Anyone did come across similar case?

Spring Data JPA: Using multiple entity in SpEL notation?

I used SpEL for generic entity name in my Spring Data JPA repositories. This time, I need to join 2 tables via JPQL and for this purpose, I am wondering if I can use multiple entity by passing to the repository and then using it in my query as SpEL 's ${#entityName}. So, is it possible?
DiningRepository:
#Query("select d as dining, dg as diningGroup, s as site " +
"from Dining d " +
" join DiningGroup dg on d.groupUuid = dg.uuid " +
" join Site s on dg.siteUuid = s.uuid " +
"where d.uuid = :uuid")
Optional<GroupAndSiteProjection> findByUuid(#Param("uuid") UUID uuid);
Here is projection where I collect Dining, DiningGroup and ``Site` result:
public interface GroupAndSiteProjection {
Dining getDining();
DiningGroup getDiningGroup();
Site getSite();
}
The method is in DiningRepository and ${#entityName} gets Dining entity. But I want to use also DiningGroup by passing it to the repository as generic e.g. DiningRepository<Dining, DiningGroup>... Is it possible?

Query String with native query and ordered parameter, sql doesn't work

I have the following code
#Query(nativeQuery = true, value = "select e.* from event e"
+ " join league l on (l.id = e.league_id)"
+ " join sport s on (l.sport_id = s.id)"
+ " join team t1 on (t1.id = e.team_one_id)"
+ " join team t2 on (t2.id = e.team_two_id)"
+ " join country c on (c.id = l.country_id)"
+ " where l.name LIKE %?1%")
Page<Event> getAllEventsFiltered(final PageRequest of, final String filter);
If execute this SQL into database I receive a lot of results but when is executed from java I receive no one result in the same SQL.
I already tried:
where l.name LIKE %?#{escape([1])} escape ?#{escapeCharacter()}
but just works to begins and I needs for both begin and end.
JDBC parameters can only be included in very specific places in a SQL statement. They are not replaced as strings in the SQL statement but they are applied. The specific valid places change from database to database, and also depend on the JDBC driver variant/version.
The general rule is that a parameter can be applied where a single value would be present. String parameters should not be enclosed in single quotes as a VARCHAR would be.
One option to make it compliant, is to place the parameter isolated from other text, for example by using the CONCAT() function. Your query could be rephrased as:
#Query(nativeQuery = true, value = "select e.* from event e"
+ " join league l on (l.id = e.league_id)"
+ " join sport s on (l.sport_id = s.id)"
+ " join team t1 on (t1.id = e.team_one_id)"
+ " join team t2 on (t2.id = e.team_two_id)"
+ " join country c on (c.id = l.country_id)"
+ " where l.name LIKE concat('%', ?1, '%')") // change here
Nevertheless, the specific syntax change can be different depending on the database you are using (that you haven't mentioned).

sql to hql throwing exception

I'm using hibernate in my project and I'm trying to convert an existing sql query from DaoImplementation class to hql,
The sql query I have is
JdbcTemplate select = new JdbcTemplate(dataSource);
String sql = "SELECT * FROM (SELECT site_id,rtc,sigplan,cycle_time,health,phase_no,phase_time,active_groups,groupscolour,ip "+
"FROM status_data where rtc>='" + fromDate + "' and rtc<'" + toDate + "' and "+
"site_id=" + SiteId + " order by rtc desc limit "+recordLimit+" )as temp ORDER BY RTC ASC";
I wrote the hql version to get data from HealthLog table as
String hql = " select f from (select h from HealthLog h where rtc>='"+fromDate+"' and rtc <'"+toDate+"' "
+ "and siteId = "+siteId+" order by rtc desc limit "+limit+" ) as f order by rtc asc ";
return super.readListByHql(hql);
But the above hql throws the following exception
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 1, column 16 [ select f from (select h from com.traff.hibernate.model.HealthLog as h where rtc>='1974-08-01 14:10:00.0' and rtc <'1974-09-01 23:46:20.6' and siteId = 20 order by rtc desc limit 50000 ) as f order by rtc asc ]
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:54)
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:47)
at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:79)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:276)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:180)
at org.hibernate.hql.intern
I also tried the below code snippet but that giving me wrong results
Criteria criteria = createEntityCriteria();
criteria.add(Restrictions.ge("rtc", fromDate));
criteria.add(Restrictions.lt("rtc", toDate));
criteria.add(Restrictions.eq("siteId", siteId));
criteria.setMaxResults(limit);
criteria.addOrder(Order.asc("rtc"));
criteria2 = criteria;
criteria2.addOrder(Order.desc("rtc"));
return criteria2.list();
Which is the correct way to achieve the result?
First of all, as already mentioned in the comments, you cannot do a subquery within the FROM clause in HQL.
See: Hibernate Documentation
Secondly, the limit keyword is not supported by HQL.
Usually you would use query.setFirstResult(0) and query.setMaxResults(recordLimit) methods where query has the type of the Query Interface. But since you are using the limit in a subquery, there is no way.
See: How to set a limit to inner query in Hibernate?
Some options:
Use a native SQLQuery
Since you are only sorting in the outer Query. You could only execute the inner query and sort in Java.
Example for Option 2:
Session session = factory.openSession();
Query query = session
.createQuery("FROM HealthLog "
+ "WHERE rtc >= :rtcL and rtc < :rtcG and siteId = :siteId "
+ "ORDER BY rtc DESC");
query.setParameter("rtcL", fromDate);
query.setParameter("rtcG", toDate);
query.setParameter("siteId", siteId);
query.setFirstResult(0);
query.setMaxResults(recordLimit);
List<HealthLog> res = query.list();
session.close();
Collections.sort(res, new Comparator<HealthLog>() {
public int compare(HealthLog o1, HealthLog o2) {
return o1.getRtc().compareTo(o2.getRtc());
}
});
The query above returns HealthLogs with all attributes. If you want to only retrieve specific attributes, you can add a SELECT new HealthLog(siteId,rtc,sigplan,cycle_time,...) to your Query with a fitting constructor in HealthLog.
Please note that the code snippet might not be ready to use, since i do not know your model and attribute names.

How do I write join in Ebean Java ORM language

Currently my code is
int customerId = 4;
String sql = "select id from coupon as A join coupon_use "
+ "as B on A.id=B.coupon where B.customer=" + customerId
+ " and B.like_at is not null;";
RawSql rawSql = RawSqlBuilder.parse(sql).create();
Query<Coupon> query = Ebean.find(Coupon.class);
query.setRawSql(rawSql);
List<Coupon> list = query.findList();
return ok(Json.toJson(list));
How do I avoid writing manual sql query but still have the ORM generate that query and return me the result?
Ebean will add appropriate joins based on the paths/properties used in the where and order by etc.
where couponUse.likeAt is not null.
Assuming couponUse.likeAt is the correct expression path ... Ebean will add a join to support the expression automatically.

Categories

Resources