#Repository
public interface GroupRepository extends JpaRepository<Group, String> {
//Other queries....
#Query(value = "with cte(group_id, parent_group_id, group_name) as( "
+ "select group_id, parent_group_id, group_name "
+ "from hea.hea_group "
+ "where group_id = ?1 "
+ "union all "
+ "select g.group_id, g.parent_group_id, g.group_name "
+ "from hea.hea_group g "
+ "inner join cte on cte.group_id = g.parent_group_id "
+ "where g.parent_group_id is not null "
+ ") select * from cte", nativeQuery = true)
List<Object> getChildGroups(String groupId);
}
Above is the query that I have written that should return the parent group and all of its children. The query does what it is suppose to do when I replace the ?1 with a hard coded group id value and change the method to have no parameters, but when I try to run it as above it returns nothing even though I'm passing in the exact same value that I was hard coding.
Below is the sql that is being generated by the query. When I replace the ? with a group id an run it on a test database it returns the results that it should.
with cte(group_id, parent_group_id, group_name) as( select
group_id,
parent_group_id,
group_name
from
hea.hea_group
where
group_id = ?
union
all select
g.group_id,
g.parent_group_id,
g.group_name
from
hea.hea_group g
inner join
cte
on cte.group_id = g.parent_group_id
where
g.parent_group_id is not null ) select
*
from
cte
The variables are zero based so ?0 is what you should use.
Related
I need the user id, user name, asesor nombre, asesor telefono, asesor correo and the tipo asesor but the json response repeat data.
this is the sql query in the spring reposotiry.
'''
#Query( value = "SELECT U.id as userid, u.name as cliente," +
"A.nombre, A.correo, A.telefono, TA.tipo as asesoria " +
"from tc_users U, tc_usuario_asesores UA , " +
"tc_asesor A,tc_tip_asesor TA " +
"where U.id = UA.userid " +
"and UA.asesorid= A.id " +
"and A.tipo_asesor = TA.id",
nativeQuery = true)
'''
and this query in sql workbench return this data
query in sql workbench
but the json response return this data
Json response
and dont know because this haappend, a need help with this, sorry for my bad inglish.
Your query returns a cartesian product because of the join.
You can add DISTINCT to get unique rows.
#Query( value = "SELECT DISTINCT U.id as userid, u.name as cliente," +
"A.nombre, A.correo, A.telefono, TA.tipo as asesoria " +
"from tc_users U, tc_usuario_asesores UA , " +
"tc_asesor A,tc_tip_asesor TA " +
"where U.id = UA.userid " +
"and UA.asesorid= A.id " +
"and A.tipo_asesor = TA.id",
nativeQuery = true)
i am trying to execute below sub query in spring jpa, but it is returning 0 records, but same query is returning records in this link fiddle
#Query(value = " SELECT id FROM (SELECT *, SUM(total_quantity) OVER (ORDER BY created_dttm DESC) "
+ "- total_quantity AS tq_sum FROM t) sub_query WHERE type= ?1 and tq_sum < ?2", nativeQuery = true)
public List<LubricantStock> findAllLubeStockForLubeTypeAndTotalQuantity(int lube_type_id, double total_quatity);
is there any limitations using subquery in spring jpa
A user can perform actions based on an occurrence value. When this value is equal to 'DAILY', I would like to retrieve all daily actions that have not been completed the last 24 hours.
The working SQL query:
SELECT distinct a.* FROM action as a LEFT OUTER JOIN history as h
ON a.id = h.action_id
AND h.user_id= <user> WHERE a.occurrence = 'DAILY' AND (h.id is NULL OR h.entry_date < TIMESTAMP 'yesterday')
The equivalent native query:
#Query(value =
"SELECT distinct a.* FROM action a "
+ "LEFT OUTER JOIN history h "
+ "ON a.id = h.action_id "
+ "AND h.user_id = :userId "
+ "WHERE a.occurrence='DAILY' AND (h.id IS NULL OR h.entry_date < :yesterday) ", nativeQuery = true)
public List<Action> findAllAvailableActions(#Param("userId") Long userId, #Param("yesterday") ZonedDateTime yesterday);
How it is called in my service :
ZonedDateTime today = ZonedDateTime.now(ZoneOffset.UTC);
ZonedDateTime yesterday = today.minus(1,ChronoUnit.DAYS);
Long userId = userDTO.getId();
List<Action> result = actionRepositoryCustom.findAllAvailableActions(userId, yesterday);
However, I do get the wrong results in my tests (actions that have already been completed are returned). I am afraid this is linked to the date parameter. The attribute entry_date is declared as ZoneDateTime in my entity. What am I doing wrong ?
hibernate : 5.2.4
You can't pass a ZonedDateTime into a native SQL query. You need to convert it to Calendar:
#Query(value =
"SELECT distinct a.* FROM action a "
+ "LEFT OUTER JOIN history h "
+ "ON a.id = h.action_id "
+ "AND h.user_id = :userId "
+ "WHERE a.occurrence='DAILY' AND (h.id IS NULL OR h.entry_date < :yesterday)", nativeQuery = true)
public List<Action> findAllAvailableActions(#Param("userId") Long userId, #Param("yesterday") Calendar yesterday);
And you can convert your ZonedDateTime this way:
public Calendar convertToDatabaseColumn(ZonedDateTime entityAttribute) {
if (entityAttribute == null) {
return null;
}
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(entityAttribute.toInstant().toEpochMilli());
calendar.setTimeZone(TimeZone.getTimeZone(entityAttribute.getZone()));
return calendar;
}
This approach is described here: link
I'd like to show the number of records in the history table grouped by name of service
service(code,name)
history(id, code,....)
Please note that there is no relationship between the two table history and service, history stores the activity independently from the other tables
I have tested this sql query and it returns the expected result:
select s.name, count(*) from history c
join service s
on c.code=s.code
where c.state='INITIALE'
group by s.name
Actually, I'd like to write it in jpql, I did alike
Query query =entityManager.createQuery(" select s.name, count(*) from ServiceEntity s join"
+ " HistoryEntity c "
+ " where c.code=s.code and c.state='INITIALE'"
+ " group by c.name order by c.name"
);
I got this error : Path expected for join!....
Invalid path: 'c.code'....right-hand operand of a binary operator was null....unexpected end of subtree
Try this
Query query = entityManager.createQuery("select s.name, count(s) from ServiceEntity s, HistoryEntity c "
+ " where c.code = s.code and c.state = 'INITIALE'"
+ " group by s.name order by s.name"
);
I have two tables
EmpInf
EmpId,
EmpName,
Salary,
DepartNumber.
Dept
DeptNo,
Deptname,
I also have a listview1 and dropdownlist1 which is bound to EmpInf.EmpName
While passing a particular query
FilterControl.DataClasses1DataContext obj = new DataClasses1DataContext();
protected void DropDownList1_SelectedIndexChanged1(object sender, EventArgs e)
{
var a = from r in obj.EmpInfs join s in obj.Dept1s on r.DeptNumber equals s.DeptNo where r.EmpName == "'" + DropDownList1.SelectedValue + "'" select s;
ListView1.DataSource = a;
ListView1.DataBind();
}
Whenever I select a particular name from a dropdownlist, it returns No data was returned. What particular code am I missing or is there any other error?
Put a breakpoint in SelectedIndexChanged1 and look at the value of SelectedValue to make sure DropDownList1.SelectedValue has the Employee name. You can also try DropDownList1.SelectedText.
string selected = DropDownList1.SelectedValue.ToString();
// e = employee | d = department
var query =
from e in obj.EmpInfs
join d in obj.Dept1s on e.DeptNumber equals d.DeptNo
where e.EmpName == "'" + DropDownList1.SelectedValue + "'"
select d;
Change this line:
where e.EmpName == "'" + DropDownList1.SelectedValue + "'"
to this one:
where e.EmpName == selected
OK, my last attempt here... Do this before databinding:
ListView1.DataSource = query.ToList();
Most likely the problem here is with your addition of the single quotes on the search criteria in your Where clause:
var a = from r in obj.EmpInfs
join s in obj.Dept1s on r.DeptNumber equals s.DeptNo
where r.EmpName == "'" + DropDownList1.SelectedValue + "'"
select s;
Assuming DropDownList1.SelectedValue is "Smith" then your generated sql will be along the lines of:
SELECT *
FROM <tables>
WHERE EmpName = ''Smith''
Notice the double single quotes. To double check this, put a breakpoint after your query is generated and then call .ToString() on it to get the equivalent TSQL. To fix this, remove the "'" from your LINQ query as that will be automatically added for string parameters:
var a = from r in obj.EmpInfs
join s in obj.Dept1s on r.DeptNumber equals s.DeptNo
where r.EmpName == DropDownList1.SelectedValue
select s;