JPA Criteria API checking if entity collection contains certain elements or one of them - jpa

I am wondering how to create predicate which will filter entities which collection property contains elements from collection given as parameter using JPA specification.
In this example I am building query for UserEntity to return users which belong to groups contained in parameter List.
List<String> groups = query.getGroups();
predicates.add(cb.isTrue(r.get("groups").in(groups)));
But if I understand it correctly it will return true if all or less groups are in this list.
I am looking for solution where a) all elements from list are in entity collection b) at least one (or like way)
Is there some easy way to achieve this? In fact I don't really need anything from GroupEntity so I don't think joining is necessary
Thanks for help

Related

JPQL query: Item that belongs to multiple categories

Having an entity Items that have a collection field called categories, I need to find items that belong at least to two specific categories, but I cant find the way to build the correct JPQL query.
#Entity
public class Items {
#ManyToMany (fetch = FetchType.EAGER)
private List<Category> categories;
}
I can find an item that have one category:
SELECT i FROM Item i WHERE :cat MEMBER OF item.categories
I can select items with any of several categories:
SELECT i FROM Item i WHERE :cat1 MEMBER OF item.categories OR :cat MEMBER OF item.categories
But when I try to select for items that have at least two specific categories, the following query gets no items:
SELECT i FROM Item i WHERE :cat1 MEMBER OF item.categories AND :cat2 MEMBER OF item.categories
Which is the correct way to do that?
Best regards,
Pablo.
That problem happened to me with ObjectDB.
I have contacted them too, and this was the answer:
This seems to be the result of how JPQL queries are converted into SQL
like syntax before executing. MEMBER OF is implemented using JOIN with
a new synthetic variable for iteration over the collection. In your
query item.categories appears twice, but the same synthetic variable for
iterating over that collection is used for both occurrences, and that
variable cannot match both sides of the AND with the same value.
Possibly we may have to use separate iteration per MEMBER OF as the
results as demonstrated by your post seem unacceptable (although JQPL
itself has strange behaviour in some known cases due to the conversion
to JOIN). However, using separate variables may sometimes make the
query more complex and slow unnecessarily (e.g. for the OR query in
your post), so any change requires careful planning.
As a quick solution, you may replace AND of MEMBER OF with 2 explicit
JOIN variables for iteration over the collection with 2 independent
variables.
So, the solution is to use the following query:
SELECT DISTINCT item
FROM Item item JOIN item.categories cat1 JOIN item.categories cat2
WHERE cat1 = :cat1 AND cat2 = :cat2
I don't know if this a problem only for this specific JPA implementation (ObjectDB).
Anyway, if anybody has a similar problem, I hope that this post can help.

odata filtering based on the property of a relation

I am trying to filter a set based on an aspect of their item relations called "listcontact_association" which represents the N:N relationship between contacts and lists.
I can retrieve the whole set ok by getting:
/ContactSet?$select=listcontact_association,FirstName,LastName,EMailAddress1&$expand=listcontact_association
Which gives me:
But what I would like to have is to be able to only get those Contacts that belong to an specific List based on a guid:
ContactSet?$select=listcontact_association,FirstName,LastName,EMailAddress1&$expand=listcontact_association,FirstName,LastName,EMailAddress1&$filter=listcontact_association/ListId %20eq%20(guid%2787F2A0AF-A142-E411-93FA-000C29482C88%27)
This tells me:
No property 'ListId' exists in type 'System.Collections.Generic.IEnumerable`1[[Microsoft.Xrm.Sdk.Entity, Microsoft.Xrm.Sdk, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]' at position 24.
which I guess makes sense as there can be many list associations.
I am an odata newbie and can't figure out how to filter my data, so any help is appreciated.
This is because listcontact_association is a collection, in this case, you can use lamda expression based on your requirement (only list out the filter clause here):
filter by any listid match the condition.
$filter=listcontact_association/any(a:a/ListId%20eq%20(guid%2787F2A0AF-A142-E411-93FA-000C29482C88%27))
filter by all listid match the condition
$filter=listcontact_association/all(a:a/ListId%20eq%20(guid%2787F2A0AF-A142-E411-93FA-000C29482C88%27))

JPA Join Column with where condition OR filter an entities with any declarative way

I know there is an option in Hibernate to filter entites based on an #Filter annotation!
Is there an option for a JPA 2.0 version of this (i am interested in mainly non-programmatic way -> declarative e.g. persistance.xml option or annotation option)
The goal:
In our application we want to filter all entites whose attribute Active is False or 0.
And do not love to write 30 or more specific selects for this!
I hope it has a more clear way to achieve this!
The perfect functionality would be #Filter and #FilterJoinTable, referenced this answer:
Filter list contained in entity returned by jpa/hibernate query
After some investigation i may say there is no option in JPA to get a filter function with Annotation.
The closest ones to this is:
Criteria API (http://www.objectdb.com/java/jpa/query/criteria)
Manual written query (entityManager createQuery() or createNativeQuery()) for getting entites. (http://www.objectdb.com/java/jpa/query/execute)
However I think it is a missing and very needed functionality :(

Sort order in Core Data with a multi-multi relationship

Say I'm modeling a school, so I have 2 Entities: Student and Class. For whatever reason, I want each class roster to have a custom sort order. In a simple relationship, this would mean giving Student a sortOrder attribute and just sorting the list by this number. Issue is, a Student might be order 3 in one Class and order 6 in another. How would I store these orderings in Core Data in a way that I can easily access them and sort my lists properly?
Student Class
classes <<--------->> students
^ ^
| |
unordered ordered
This diagram might help explain what I'm trying to do. The students "roster" I would want to be fetched in a specific order stored somewhere, which could be any ordering. Storing this ordering is what I'm not sure how to do in a way that's the most efficient. Creating a bunch of Order objects and trying to manage the links sounds like a lot of overhead, and it feels like there must be a better way.
If the ordering of students can be described by one or more NSSortDescriptors, you could create a fetched property on the Class entity that fetches the students and applies the sort descriptor. Alternatively, it may be easier (depending on your use case) to apply the sort descriptor(s) to the NSFetchedResultsController that you're using to deal with the class' students collection.
If you can't use an NSSortDescriptor, then you'll need an index attribute (or name of your choice) on the Student entity if there's only one ordering or a collection of Order entities describing the index in each ordering for each Student. You'll be responsible for maintaing these index values. Unfortunately, there's no easy way to do this in Core Data. It's just a lot of work.
Student <<->> StudentClass <<->> Class
StudentClass
----
studentID
order
classID
Then you can select as necessary.
For example, you have a student. Fetch all StudentClass where StudentID is student.studentID. You then have the order, as well as access to the Class.
You'll likely want to add some business logic to make your life easier. Also, if you're not already using it, take a peek at MOGenerator: https://github.com/rentzsch/mogenerator
EDIT: I'd really like to know why this is getting voted down. Comments would be much appreciated.

How to sort related entities with eager loading in ADO.NET Entity Framework

Greetings,
Considering the Northwind sample tables Customers, Orders, and OrderDetails I would like to eager load the related entities corresponding to the tables mentioned above and yet I need ot order the child entities on the database before fetching entities.
Basic case:
var someQueryable = from customer in northwindContext.Customers.Include("Orders.OrderDetails")
select customer;
but I also need to sort Orders and OrderDetails on the database side (before fetching those entities into memory) with respect to some random column on those tables. Is it possible without some projection, like it is in T-SQL? It doesn't matter whether the solution uses e-SQL or LINQ to Entities. I searched the web but I wasn't satisfied with the answers I found since they mainly involve projecting data to some anonymous type and then re-query that anonymous type to get the child entities in the order you like. Also using CreateSourceQuery() doesn't seem to be an option for me since I need to get the data as it is on the database side, with eager loading but just by ordering child entities. That is I want to do the "ORDER BY" before executing any query and then fetch the entities in the order I'd like. Thanks in advance for any guidance. As a personal note, please excuse the direct language since I am kinda pissed at Microsoft for releasing the EF in such an immature shape even compared to Linq to SQL (which they seem to be getting away slowly). I hope this EF thingie will get much better and without significant bugs in the release version of .NET FX 4.0.
Actually I have Tip that addresses exactly this issue.
Sorting of related entities is not 'supported', but using the projection approach Craig shows AND relying on something called 'Relationship Fixup' you can get something very similar working:
If you do this:
var projection = from c in ctx.Customers
select new {
Customer = c,
Orders = c.Orders.OrderByDescending(
o => o.OrderDate
)
};
foreach(var anon in projection )
{
anon.Orders //is sorted (because of the projection)
anon.Customer.Orders // is sorted too! because of relationship fixup
}
Which means if you do this:
var customers = projection.AsEnumerable().Select(x => x.Customer);
you will have customers that have sorted orders!
See the tip for more info.
Hope this helps
Alex
You are confusing two different problems. The first is how to materialize entities in the database, the second is how to retrieve an ordered list. The EntityCollection type is not an ordered list. In your example, customer.Orders is an EntityCollection.
On the other hand, if you want to get a list in a particular order, you can certainly do that; it just can't be in a property of type EntityCollection. For example:
from c in northwindContext.Customers
orderby c.SomeField
select new {
Name = c.Name,
Orders = from o in c.Orders
orderby c.SomeField
select new {
SomeField = c.SomeField
}
}
Note that there is no call to Include. Because I am projecting, it is unnecessary.
The Entity Framework may not work in the way you expect, coming from a LINQ to SQL background, but it does work. Be careful about condemning it before you understand it; deciding that it doesn't work will prevent you from learning how it does work.
Thank you both. I understand that I can use projection to achieve what I wanted but I thought there might be an easy way to do it since in T-SQL world it's perfectly possible with a few nested queries (or joins) and order bys. On the other hand seperation of concerns sounds reasonable and we are in the entity domain now so I will use the way you two both recommended though I have to admit this is easier and cleaner to achieve in LINQ to SQL by using AssociateWith.
Kind regards.