Querydsl: containsKey does not work in EclipseLink - eclipselink

Consider the following property:
public class BusinessUnit {
...
#ElementCollection
#MapKeyJoinColumn(name = "permissionId")
#Enumerated(EnumType.STRING)
private Map<Permission, BusinessUnitPermissionApplyType> permissions;
...
}
The query below does not work with EclipseLink:
List<BusinessUnit> foundBUs = new JPAQuery(em)
.from(qbu)
.where(qbu.permissions.containsKey(permission))
.list(qbu);
It gives error:
Exception Description: Syntax error parsing [select bu
from BusinessUnit bu
where containsKey(bu.permissions,?1)].
[37, 68] The expression is not a valid conditional expression.
Of course, there is no containsKey function in JPQL. Could therefore containsKey be properly emulated? For example, by performing a subquery.
What is another way to perform the same query? I tried to join permissions, i.e.:
.join(qbu.permissions)
But this does not help, since this expression doesn't allow to examine key's value. What would be really helpful is:
.joinKey(qbu.permissions, qperm)
.where(qperm.eq(permission))

Related

GORM many2many preload error

Currently using GORM to connect to two databases: POSTGRES AND sqlite (using a code switch to choose which one to use). I have a 2 database tables defined in my schema that look like this:
type TableClient struct {
Model
Synchronised bool
FacilityID string `gorm:"primary_key"`
Age int
ClientSexID int
MaritalStatusID int
SpecificNeeds []TableOptionList`gorm:"many2many:options_specific_needs"`
}
type TableOptionList struct {
ID int `gorm:"primary_key"`
Name string
Value string
Text string
SortKey int
}
Previously, I would preload related table with code like this:
var dbClient TableClient
Db.Where("facility_id = ? AND client_id = ? AND id = ?;", URLFacilityID, URLClientID, URLIncidentID).
Preload("ClientSex").
Preload("MaritalStatus").
Preload("CareTakerRelationShip").
Preload("HighestLevelOfEducation").
Preload("Occupation").
Preload("SpecificNeeds").
First(&dbClient)
Now that lookup fails with a syntax error and when I look at the SQL generated, it shows the following SQL is generated:
SELECT * FROM "table_option_lists" INNER JOIN "options_specific_needs" ON "options_specific_needs"."table_option_list_id" = "table_option_lists"."id" WHERE (("options_specific_needs"."table_client_id","options_specific_needs"."table_client_facility_id") IN (('one','LS034')))
Pasting that into the sqlite console also fails with the same error: (near ",": syntax error)
The crux of your issue is in your WHERE clause, you need to use "OR", not ",".
This is likely an issue with GORM and you could open a GitHub issue with them for this. You can get around the issue using db.Raw() from GORM. In general, I prefer to avoid ORMs. Part of the reason is it is often easier to just build an SQL query by hand than try to figure out the strange way to do it in the ORM (for things beyond basic CRUD).

QueryDsl: Exception "argument type mismatch" with projection bean and oneToMany or manyToMany association

I have an association manyToMany between User and Role entities (User >---< Role)
I wanted to perform this query:
createQuery()
.from(qUser)
.leftJoin(qUser.roles, qRole)
.where(qUser.login.eq(login))
.singleResult(
Projections.bean(User.class,
qUser.id,
qUser.login,
qUser.password,
GroupBy.set(Projections.bean(Role.class,
qRole.id,
qRole.code
)).as(qUser.roles)
)
);
The generated query looks like this, for me it's perfect:
SELECT user0_.ID AS col_0_0_,
user0_.LOGIN AS col_1_0_,
user0_.PASSWORD AS col_2_0_,
role2_.ID AS col_4_0_,
role2_.CODE AS col_5_0_
FROM public.USER user0_
LEFT OUTER JOIN public.USER_ROLE roles1_ ON user0_.ID=roles1_.USER_ID
LEFT OUTER JOIN public.ROLE role2_ ON roles1_.ROLE_ID=role2_.ID
WHERE user0_.LOGIN=? LIMIT ?
But I have a java.lang.IllegalArgumentException: argument type mismatch.
I debugged and I found out that data from database id loaded without problem. This is when QueryDsl/Hibernate did some introspection to create and initialise my entities that the exception is throwed.
The problem is that the User.setRoles(Set<Role>) method has called with a long parameter: The ID of the first Role entity list of the User. Instead of create a Set of Role an then associate these roles to the User.
Is there a problem with the query? Or is it not supported by QueryDsl?
I am using the QueryDsl 3.6.6 (I tested with 3.7.4: same result)
I guess that the java.lang.IllegalArgumentException: argument type mismatch are thrown not by the JOIN comparing and you can verify that by verifing the ID type of the 3 tables UTILISATEUR, ROLE and USER_ROLE.
If there is a difference on type between
UTILISATEUR.ID=USER_ROLE.USER_ID
or
USER_ROLE..ROLE_ID=ROLE.ID
so that's the probleme.
If there is not a problem , the exception is thrown by the test of equality of the login.
But, I suspect that the USER_ROLE join table did not connect with the correct table. You may have two tables USER and UTILISATEUR . Unless you renamed the join table.
I have had same error as you,
I try different ways and it took a lot of time.Eventually I founded this way,
My classes are:
Lesson
LessonScores for saving user scores
LessonScoresModel for returning data and
LessonScoresModel.ScoresModel is a static nested class
I need some information about user scores in a class.
I use below query for returning data.
I use exact related models for retuning data but it's gives the beatiful "argument type mismatch" error.
So I developed a static class for returning data.
JPAQuery query = new JPAQuery(em);
//select from which model you need
query.from(QLessonScores.lessonScores);
//use your condition
query.where(predicate);
//use query and returning data
Map<Lesson,List<LessonScoresModel.ScoresModel>> map = (Map<Lesson,List<LessonScoresModel.ScoresModel>>)
//use tranform for making group by
query.transform(GroupBy.groupBy(QLessonScores.lessonScores.lesson).as(
//return list of data which column we need
GroupBy.list(Projections.fields(LessonScoresModel.ScoresModel.class,
QLessonScores.lessonScores.score.as("score"),
QLessonScores.lessonScores.scoresType.as("scoresType"),
QLessonScores.lessonScores.success.as("success")
))
));
you will find more information in these links,
codata
programcreek

NH QueryOver FetchMany Exception

I am trying to query a parent User and then their UserRoleMappings. I have something similar to the below statement:
Dim userObj As User = session.Queryable(Of User)().Where(Function(x) x.username.Equals("someone")).FetchMany(Function(y) y.UserRoleMappings).SingleOrDefault()
When I try to run this statement I get the following exception:
A fetch request must be a simple member access expression; 'Convert(y.UserRoleMappings)' is a UnaryExpression instead.
Parameter name: relatedObjectSelector
I can confirm that I got this to work in a C# Test Case, but unfortunately I need it to work in VB. Can anyone assist?

LINQ display row numbers

I simply want to include a row number against the returned results of my query.
I found the following post that describes what I am trying to achieve but gives me an exception
http://vaultofthoughts.net/LINQRowNumberColumn.aspx
"An expression tree may not contain an assignment operator"
In MS SQL I would just use the ROWNUMBER() function, I'm simply looking for the equivalent in LINQ.
Use AsEnumerable() to evaluate the final part of your query on the client, and in that final part add a counter column:
int rowNo = 0;
var results = (from data in db.Data
// Add any processing to be performed server side
select data)
.AsEnumerable()
.Select(d => new { Data = d, Count = ++rowNo });
I'm not sure whether LINQ to SQL supports it (but it propably will), but there's an overload to the Queryable.Select method that accepts an lambda with an indexer. You can write your query as follows:
db.Authors.Select((author, index) => new
{
Lp = index, Name = author.Name
});
UPDATE:
I ran a few tests, but unfortunately LINQ to SQL does not support this overload (both 3.5sp1 and 4.0). It throws a NotSupportedException with the message:
Unsupported overload used for query
operator 'Select'.
LINQ to SQL allows you to map a SQL function. While I've not tested this, I think this construct will work:
public partial class YourDataContext : DatContext
{
[Function(Name = "ROWNUMBER")]
public int RowNumber()
{
throw InvalidOperationException("Not called directly.");
}
}
And write a query as follows:
from author in db.Authors
select new { Lp = db.RowNumber(), Name = author.Name };

Nhibernate.Search, Lucene, and the Criteria API: types mismatch

Update
I've been looking around the NHibernate.Search.Tests project to find out how the Criteria API is used (i find it immensely useful to look around the test code to have working examples) and i noticed that the way to use the Fulltext search is radically different. Here are two tests, one with the criteria API, one with the classic query schema:
[Test]
public void ResultSize()
{
IFullTextSession s = Search.CreateFullTextSession(OpenSession());
ITransaction tx = s.BeginTransaction();
// snipped the objects creation
QueryParser parser = new QueryParser("title", new StopAnalyzer());
Lucene.Net.Search.Query query = parser.Parse("Summary:noword");
IFullTextQuery hibQuery = s.CreateFullTextQuery(query, typeof(Clock), typeof(Book));
Assert.AreEqual(0, hibQuery.ResultSize);
// snipped the end of the test
}
[Test]
public void UsingCriteriaApi()
{
IFullTextSession s = Search.CreateFullTextSession(OpenSession());
ITransaction tx = s.BeginTransaction();
// snipped creation
IList list = s.CreateCriteria(typeof(Clock))
.Add(SearchRestrictions.Query("Brand:seiko"))
.List();
Assert.AreEqual(1, list.Count, "should get result back from query");
// snipped deletion
}
The second solution works under vb.net, at the cost of the useful Lucene query (which embarks it's own total of the corresponding rows) and at the cost of the Lucene ordering (or i couldn't find it)
Hello everyone,
yet again, i'm stumped on the path, but this time, i suspect something a bit more sinister than my usual erratic errors (cue ominous music)
I'm trying to combine FullText search using Lucene.net with paging and the Criteria API.
So far paging and the Fulltext search have been working flawlessly. Recently though, we had to use the criteria API to add specific filters to the query. So what i did was the following:
Create the Nhibernate.Search query object using the following
Private Function GetQuery(ByVal QueryString As String, ByVal Orders() As String) As IFullTextQuery
Dim ifts As IFullTextSession = Search.CreateFullTextSession(UnitOfWork.CurrentSession)
Dim analyzer As New SimpleAnalyzer
Dim parser As New MultiFieldQueryParser(SearchPropertyNames, analyzer)
Dim queryObj As Lucene.Net.Search.Query = parser.Parse(QueryString)
Dim nhsQuery As IFullTextQuery = ifts.CreateFullTextQuery(queryObj, New System.Type() {GetType(T)})
For i As Integer = 0 To Orders.Count - 1
Orders(i) = Orders(i) & "FS"
Next
nhsQuery.SetSort(New Sort(Orders))
then add my Criteria to the query:
Dim crit As ICriteria = ifts.CreateCriteria(GetType(T))
Dim criterion As ICriterion
If criteria IsNot Nothing Then
For Each criterion In criteria
If (Not criterion Is Nothing) Then
crit.Add(criterion)
End If
Next
End If
nhsQuery.SetCriteriaQuery(crit)
but when i list the resulting query, i receive the following exception
Criteria query entity should match query entity
A quick glance in the FullTextQueryImpl source file (method GetLoader) shows that there is a comparison between the type name given to the NHibernate.Search query object and the EntityOrClassName property for the Criteria object. That's where my problems appear because the FullTextQueryImpl uses the Name, and the Criteria uses the Fullname. Here's a constructor code for the CriteriaImpl class
Public Sub New(ByVal persistentClass As Type, ByVal session As ISessionImplementor)
Me.New(persistentClass.FullName, CriteriaSpecification.RootAlias, session)
Me.persistentClass = persistentClass
End Sub
and here's the comparison:
Dim entityOrClassName As String = DirectCast(Me.criteria, CriteriaImpl).EntityOrClassName
If ((Me.classes.GetLength(0) = 1) AndAlso (Me.classes(0).Name <> entityOrClassName)) Then
Throw New SearchException("Criteria query entity should match query entity")
End If
As a result, the comparison fails and the exception is thrown. I tried playing around with the aliases to no avail since the comparison is not using the aliases.
Am i missing something huge in my mix of the Fulltext search and the Criteria API, or is it something else? Does it work as expected in C#, because i'm having a weird feeling that it could be vb.net related?
Thank you for reading,
Samy
Looks like this has been resolved with revision 1611 of NHibernate.Search :
Revision: 1611
Message: Fixed a bug where a full class name was being compared against a partial one. This was causing LuceneQueryTest.UsingCriteriaApi to fail.
Modified : /trunk/src/NHibernate.Search/src/NHibernate.Search/Query/FullTextQueryImpl.cs
svn : https://nhcontrib.svn.sourceforge.net/svnroot/nhcontrib/trunk/src/NHibernate.Search/