Spring security data unable to fetch the results - spring-security

I want to fetch all the orders if the user role is ROLE_ADMIN, else fetch me only the orders matching the customer id.
#Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
#Query("select o from Order o inner join o.customer c where c.id = ?#{hasRole('ROLE_ADMIN') ? '%' : principal.id}")
Page<Order> findAll(Pageable pageable);
I am getting the below response
Parameter value [%] did not match expected type [java.lang.Long (n/a)]
Where am I going wrong?

The id of a customer is supposed to be a number (Long). But when the role matches ROLE_ADMIN, you are returning a char: %.
I think the person that suggested this solution was copying from another example that was using a LIKE operation and didn't realized that it's wrong in this case.
I think you can try something like this:
#Query("select o from Order o inner join o.customer c where true = ?#{hasRole('ROLE_ADMIN')} or c.id = ?#{principal.id}")
But I don't know if this is the right approach

Related

Grails executeQuery subquery

im using grails 2.4.5
i want to retrieve the top 3 customers based on how many contracts they have
im trying to execute this code
def customers = Customer.executeQuery("Select cu, (Select count(*) from Contract co where co = cu.contract) from Customer cu",
[max: 3])
and it returns this error
left and right hand sides of a binary logic operator were incompatibile [com.cms.Contract : java.util.Set(com.cms.Customer.contract)]
i understand that the co and cu.contract types are not the same but i dont get why. can someone help me how this executeQuery of grails work. this is the only framework i used that have a static query execution but still need to follow a certain format.
what i really want to do is to generate a query like this
Select * from Customer cu order by (Select count(*) from Contract co where co.id = cu.id)
You could try a Criteria query with projections:
def results = Customer.createCriteria().list() {
createAlias( 'contracts', 'contractalias' )
projections {
groupProperty( 'contractalias.contract' )
count( 'contractalias.contract', 'contractCount' )
}
maxResults( 3 )
order 'contractCount', 'desc'
}
I'm not 100% of your field names so had to assume in above query.
It's often useful to turn on sql logging when trying out these queries e.g. add following to development DataSource
development {
dataSource {
...
logSql = true
}
}

Cannot figure out this complex query

I have three tables and I am having trouble getting to the bottom of this one.
So I am given the ID of a vehicle, and I need to write a query to output a list of its seat rows.
Vehicle
{
id,
vehicleTypeId,
color
}
VehicleType
{
id,
type,
}
VehicleSeats
{
id,
description
}
This is as far as my query has gotten and I am just as a complete loss on getting this one out right. I need it to output a list of seats, not a list of types, I just do not know how to take it deeper.
var vehicleSeatsList = (from c in db.Vehicle
where c.VehicleTypeID == id
select c).ToList();
Here was my final solution. I have yet to plug it in to know if it is right. I was being a dummy. Dont know why I wasn't thinking of just doing a join...
var VehicleTypeSeats = (from c in db.VehicleTypeSeats
join a in db.Vehicles on c.AircraftTypeID equals a.VehicleTypeID
where c.VehicleTypeID == id
select c).ToList();
Assuming this is in SQL, there is no relationship between your VehicleSeats and Vehicle tables. You would need to add VehicleSeats.vehicleID or something like that. If you did, the below would work:
SELECT VehicleSeats.description
FROM VehicleSeats, Vehicle
WHERE VehicleSeats.vehicleID = Vehicle.id
AND Vehicle.id = {your given vehicle ID};
Simply inner join Vehicle and Vehicle seats on their common column then add the where statement.
var VehicleTypeSeats = (from c in db.VehicleTypeSeats
join a in db.Vehicles on c.AircraftTypeID equals a.VehicleTypeID
where c.VehicleTypeID == id
select c).ToList();

How to deal with Null Values in OUTER JOINS using Entity Framework 6

I need to process the query at the bottom of this post in C#. The query works, but I don't know how to use it in EF6. I used a method and a viewmodel for it (variable query = the query below). But when it encounters null values in the OUTER JOIN, int32 cant accept this value when calling .toList(). What's the best way to deal with it?
var result = context.Database.SqlQuery<TourQueryViewModel>(query);
var reslist = result.ToList();
I tried my first steps with LINQ, but I dont get it how to translate into LINQ itself or the query-methods, that are equivalent to it. So I am hoping for your help.
SELECT toursdata.TourId AS TourId, toursdata.Tourname AS Tourname,toursdata.Tourdate Tourdate,
toursdata.VehicleId AS VehicleId, toursdata.VehicleName AS VehicleName, toursdata.LicenseNumber AS LicenseNumber,
Employees.EmployeeId AS EmployeeId, Employees.Gender AS Gender, Employees.Forename AS Forename, Employees.Surname AS Surname
FROM (
SELECT te.TourId, te.Tourname, te.Tourdate,
Vehicles.VehicleId, Vehicles.VehicleName, Vehicles.LicenseNumber,
TourEmployees.EmployeeId
FROM TourEmployees RIGHT OUTER JOIN Tours AS te ON TourEmployees.TourId = te.TourId,
Tours AS tv INNER JOIN Vehicles ON tv.VehicleId = Vehicles.VehicleId
WHERE tv.TourId = te.TourId
) toursdata
LEFT OUTER JOIN Employees ON toursdata.EmployeeId = Employees.EmployeeId
To eliminate the null problem, I changed the data type of the corresponding entity-attribute to a nullable-type
int turned to int?.
Didnt know about that language feature.

Grails left outer join query HQL or criteria challenge

I am a newbie to hql and tried out several combinations that i could find but i seem unable to construct the correct HQL query for a left join.
I have the following domain model:
class Company {
static hasMany = [employees: Employee]
}
class Employee {
static belongsTo = [
Company
]
}
So a employee does not know anything about the companies. Now i would like to create a hql query that gives met the employees without a company. In sql i have successfully created the query using a left join but i seem not to be able to create a criteria or hql query that gives me a correct result.
Any a clue or some tips on how i could achieve the result?
Here you go, this works:
Employee.executeQuery("""
Select e
from Employee e
where e not in (Select ce from Company c left join c.employees ce)
""")

Is my IQueryable syntax correct?

The generated SQL does a cross join but as the ID's are matched it acts like an inner join but is there a better performing way to do this by actually using the join keyword in C#? Is there a way where you don't have to specify how the properties join because they are all heirarchicly related anyway
Item is a Page class
PageRoles is an IQueryable property in a Page class
aspnet_Roles is an IQueryable property in a PageRole class
var item = _repository.GetByKey(999);
var f = (from fd in item.PageRoles
from k in fd.aspnet_Roles
where Roles.GetRolesForUser().Contains(k.RoleName)
&& k.RoleId == fd.RoleId
select k.RoleName)
.Count();
EDIT:
Here is an example of an IQueryable property in my classes. The below example comes from the PageRole class
public IQueryable<aspnet_Role> aspnet_Roles
{
get
{
var repo=NorthCadburyWebsite.Models.aspnet_Role.GetRepo();
return from items in repo.GetAll()
where items.RoleId == _RoleId
select items;
}
}
Does this compile or do you get an error?
In this case, as you mentioned, you don't need a join.
I haven't used this syntax, but it looks like you use k as a refererence (like an alias in sql syntax)
This should deliver the same result (without even using k):
var f = (from fd in item.PageRoles
where Roles.GetRolesForUser().Contains(fd.aspnet_Roles.RoleName)
&& fd.aspnet_Roles.RoleId == fd.RoleId
select fd.aspnet_Roles.RoleName)
.Count();
Note: Not tested, just a guess.
I don't have my Intellisense with me but I think you can:
var f = (from fd in item.PageRoles
join k in fd.aspnet_Roles on k.RoleId equals fd.RoleId
where Roles.GetRolesForUser().Contains(k.RoleName)
select k.RoleName)
.Count();
I think I'm confused, because I'm seeing the following hierarchy in your query which isn't making any sense:
[PageRoles]
|--RoleId <~~~~~~~~~.
|--[aspnet_Roles] |
|--RoleId ~~~~~~~*
|--RoleName
Is the hierarchy determined by the RoleId and you only mean for PageRoles.RoleId to reference aspnet_Roles.RoleId? So you might have something like:
[PageRoles] [aspnet_Roles]
|--RoleId |--RoleId
|--RoleName
And you're trying to make it into the following:
[PageRoles]
|--RoleId
|--[aspnet_Roles] (where RoleId == PageRoles.RoleId)
|--RoleName
...?
In which case if you can't do the following, then something is wrong with your IQueryable property definitions and not the query you have posted. Namely the method to get PageRoles's aspnet_Roles child rows is not set up properly.
var f = (from fd in item.PageRoles
from k in fd.aspnet_Roles
where Roles.GetRolesForUser().Contains(k.RoleName)
select k.RoleName)
.Count();
(fd.aspnet_Roles should already be constrained by RoleId and generate an inner join).
You can check your hierarchy by seeing what SQL is generated from:
var f = from fd in item.PageRoles
from k in fd.aspnet_Roles
select k;
which should vaguely resemble (with something having to do with item thrown in):
SELECT k.RoleName, k.SomethingElse
FROM PageRoles fd
INNER JOIN aspnetRoles k ON fd.RoleId = k.RoleId;
I'm sure I'm missing something, so please help me fill in the blanks...

Resources