Pass date parameter to native query - spring

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

Related

Response json not equals to sql query

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)

jpql native query not setting parameter

#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.

using one list value in another list using anonymous types

I have a list x with anonymous types in which i want to use a value which pre-calculated
int count1 =
(from users in dc.BeadSets
where users.UserId == i
select users
).Count();
var x =
(from users in dc.Users
where users.Id == i
select new { username = users.UserName
, fullname = users.FirstName + " " + users.LastName
, userid = users.Id
}
).ToList();
Now this is working fine as usual
Cannot implicitly convert type 'System.Collections.Generic.List<AnonymousType#1>'
to 'System.Collections.Generic.List<AnonymousType#2>'
but while i am trying to use like this its throwing above error
int count1 =
(from users in dc.BeadSets
where users.UserId == i
select users
).Count();
x =
(from users in dc.Users
where users.Id == i
select new { beadsets= count1
, username = users.UserName
, fullname = users.FirstName + " " + users.LastName
, userid = users.Id }
).ToList();

linq to sql: issue with linq query

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;

Can someone help me converting a SQL Query into LINQ expression?

Can someone help me converting the following SQL Query into LINQ expression?
select student.StudentID,
student.FirstName + ' ' + student.MiddleInitial + ' ' + student.LastName,
student.OpenDate,
acct.Balance
from Student student
inner join
(Select StudentID, Sum(Amount) as Balance
from Account
Group by StudentID) as acct on student.StudentID = acct.StudentID
The following LINQ expression works! Thank you so much Phil!!!
var results = (from s in Students
join a in Accounts on s.StudentID equals a.StudentID
group a by new
{s.StudentID, s.FirstName, s.MiddleInitial, s.LastName, s.OpenDate}
into z
select new
{ StudentID = z.Key.StudentID,
FirstName = z.Key.FirstName,
MiddleInitial = z.Key.MiddleInitial,
LastName = z.Key.LastName,
OpenDate = z.Key.OpenDate,
Balance = z.Sum(a=> a.Amount)
}
);
Thank you!
Give this a try?
var stu =
from s in db.Students
join a in db.Account on s.StudentID equals a.StudentID
group a by new
{s.StudentID, s.FirstName, s.MiddleInitial, s.LastName, s.OpenDate}
into z
select new
{ StudentID = z.Key.StudentID,
FullName = string.Format("{0} {1} {2}",z.Key.FirstName, z.Key.MiddleInitial, z.Key.LastName),
OpenDate = z.Key.OpenDate,
Balance = z.Sum(a=>a.Amount)
};

Resources