Join Fetch with conditions on the right table - spring

Suppose I have a OneToMany relationship:
Parent is the parent entity
Child is the child entity
Now I want to find the parent by id in JpaRepository but I want only the children ( which are lazy loaded ) that have a certain attribute isActive true. I have tried specifying this in a #Query like this:
FROM PARENTS P JOIN FETCH P.children P WHERE P.id = :id AND P.children.isActive is true.
But it dosen't return anything ( the database has data that should be returned )
Can I achieve this in a single query or should I just write another query that returns the requested children ?
Thanks !

Related

Using query hints to use a index in an inner table

I have a query which uses the view a as follows and the query is extremely slow.
select *
from a
where a.id = 1 and a.name = 'Ann';
The view a is made up another four views b,c,d,e.
select b.id, c.name, c.age, e.town
from b,c,d,e
where c.name = b.name AND c.id = d.id AND d.name = e.name;
I have created an index on the table of c named c_test and I need to use it when executing the first query.
Is this possible?
Are you really using this deprecated 1980s join syntax? You shouldn't. Use proper explicit joins (INNER JOIN in your case).
You are joining the two tables C and D on their IDs. That should mean they are 1:1 related. If not, "ID" is a misnomer, because an ID is supposed to identify a row.
Now let's look at the access route: You have the ID from table B and the name from tables B and C. We can tell from the column name that b.id is unique and Oracle guarantees this with a unique index, if the database is set up properly.
This means the DBMS will look for the B row with ID 1, find it instantly in the index, find the row instantly in the table, see the name and see whether it matches 'Ann'.
The only thing that can be slow hence is joining C, D, and E. Joining on unique IDs is extremely fast. Joining on (non-unigue?) names is only fast, if you provide indexes on the names. I'd recommend the following indexes accordingly:
create index idx_c on c (name);
create index idx_e on e (name);
To get this faster still, use covering indexes instead:
create index idx_b on b (id, name);
create index idx_c on c (name, id, age);
create index idx_d on d (id, name);
create index idx_e on e (name, town);

Hibernate, Order by count of subquery on ManyToMany using Predicates

I have a query written using Predicates in Hibernate and I need to add a subquery on a join table to count the number of joins and order by the number of joins where they exist in an array of ids.
The join table is a ManyToMany relation.
I am using flyway to setup the table schema, so while the join table exists in the database, a join model is not needed in Hibernate to join the 2 related models therefore no join model exists.
I don't care about retrieving these related models, I just want the number of joins so that I can order by them.
The following is PostGreSQL, which works. I need to convert the following PSQL into a Predicate based query:
SELECT u.*, COUNT(jui.interest_id) AS juiCount
FROM "user" u
LEFT JOIN (
SELECT ui.user_id, ui.interest_id
FROM user_interest ui
WHERE ui.interest_id IN (?)
) AS jui ON u.id = jui.user_id
GROUP BY u.id
ORDER BY juiCount DESC
Where the ids provided for the IN condition are passed into the subquery. The above query is in PostGreSQL.
Working with what I have so far:
CriteriaBuilder b = em.getCriteriaBuilder();
CriteriaQuery<User> q = b.createQuery(User.class);
Root<User> u = q.from(User.class);
// This doesn't make sense because this is not a join table
// Subquery<Interest> sq = q.subquery(Interest.class)
// Root<Interest> squi = sq.from(Interest.class);
// sq.select(squi);
// sq.where(b.in("interest_id", new LiteralExpression<Long[]>((CriteriaBuilderImpl) b, interestIds)));
q.orderBy(
// b.desc(b.tuple(u, b.count(squi))),
b.asc(u.get(User_.id))
);
q.where(p);
return em
.createQuery(q)
.getResultList();
Everything I have managed to find doesn't quite seem to fit right given that they are not using ManyToMany in the use of q.subquery() in their example.
Anyone can help fill in the blanks on this please?

How to get entities in a many-to-many relationship that do NOT have a corresponding linked entity with DQL and Doctrine?

I have a standard many-to-many relationship set up. Entity A can have many of Entity B, and vice versa.
I'm trying to get a list of all Entity A that do NOT have any corresponding Entity B. In SQL, I'd run a query like this:
SELECT a.* FROM entity_a a LEFT JOIN a_b r ON r.AID = a.id WHERE r.BID IS NULL
In this query, a_b is the linking table.
I'm trying to write a DQL statement (or use some other method) to get the same result, but the following does not work:
SELECT s FROM VendorMyBundle:EntityA s LEFT JOIN VendorMyOtherBundle:EntityB u WHERE u IS NULL
How can I achieve what I'm trying to do?
First, I have to underline that usually you should JOIN on the property of the entity (i.e. s), e.g. instead of:
SELECT s FROM VendorMyBundle:EntityA s
LEFT JOIN VendorMyOtherBundle:EntityB u WHERE u IS NULL
you should have something like:
SELECT s FROM VendorMyBundle:EntityA s
LEFT JOIN s.mylistofb u WHERE u IS NULL
where I'm supposing that in entity A you have defined your relationship as:
class A{
// ...
/**
* #ManyToMany(targetEntity="Vendor\MyBundle\Entity\EntityB")
* #JoinTable(name="as_bs",
* joinColumns={#JoinColumn(name="a_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="b_id", referencedColumnName="id", unique=true)}
* )
**/
private $mylistofb;
This stated, if the query is not working yet, then try the following:
SELECT s FROM VendorMyBundle:EntityA s
WHERE SIZE(s.mylistofb) < 1
It is simplest than the previous and also comes from the official docs (i.e. see "phonenumbers example").

entity framework lazy loading null properties in child

Using entity framwork with lazy loading - Have the following question on loading related entities when the entities
are null.
Say I have two tables employee and employeedetails. Assume in the above case not all employee entries have an entry in the employeedetails table.
If I want to look up a list of Employees
(from e in objectcontext.employees
select new EmployeeEntity
{
EmpID= e.EmployeeID,
FirstName = e.FirstName,
Address = e.employeedetails.Address
}).ToList();
EmployeeEntity is the data class into which we stuff the results.
The above code breaks if even one employee in the returned list
does not have a entry in table employeedetails. This is obvious since e.employeedetails will be null for those customers who do not have a details entry
What is the best way to rewrite the above query?
Would something like this be acceptable ?
(from e in objectcontext.employees
select new EmployeeEntity
{
EmpID= e.EmployeeID,
FirstName = e.FirstName,
Address = e.employeedetails == null ? "" : e.employeedetails.Address,
}).ToList();
I am not clear on the efficiency of this above query - Would this statment do the null check at DB level?
Should I instead do an explicit include like
objectcontext.include("employeedetails")...
And then loop through the results to check for null?
Yes, this statement would indeed perform a null check in the SQL query that is generated. Most likely, it will simply be a NVL or COALESCE.
That's the way you should be doing it.

Linq query that results in one field in parent entity being a collection of child entities

I am trying to write a Linq query that results in a parent entity with one of the fields being a collection of entities of its related children. For example, I have a collection of all customers entities and a collection of all orders entities. The orders entities have a field called customerPK which contains the link to the related parent customer entity. I want to create a Linq query that joins the two collections and results in all the fields of the customer entity plus an additional field which is the collection object of all the related order entities for that specific customer entity.
Hopefully this should do the trick;
EDIT: Code updated to perform a Left Outer Join, based on this example; http://smehrozalam.wordpress.com/2009/06/10/c-left-outer-joins-with-linq/. This now includes Customers who have no orders.
var query = from c in customers
join o in orders on c.ID equals o.CustomerPK into joined
from j in joined.DefaultIfEmpty()
group j by c into g
select new { Customer = g.Key, Orders = g.Where(x => x != null) };
Note, the use of Where on the selection of the Orders grouping is so that null orders are filtered out at this point, instead of ending up with a grouping containing a single null Order for customers who don't have orders.
Then some example usage;
foreach (var result in query)
{
Console.WriteLine("{0} (ID={1})", result.Customer.Name, result.Customer.ID);
foreach (var order in result.Orders)
{
Console.WriteLine(order.Description);
}
}
This example results in an object with two fields, the Customer and then a group of related Orders, but there's no reason why you can't select the individual fields of your customer object in the query as you specified in your post.

Resources