Converting Object to Class object - spring

in my Spring MVC project i m using Hibernate, by using Criteria API i am applying Group BY and Order BY clause. Query get executed on DB successfully and it brings result also but its an array of Object--
Here is code of Criteria API
Criteria criteria = session.createCriteria(DashboardSubindicatorSubmission.class, "DashboardSubindicatorSubmission")
.setProjection(Projections.projectionList()
.add(Projections.sum("InputValue").as("InputValue"))
.add(Projections.groupProperty("fkAccademicYearId"))
.add(Projections.groupProperty("fkAssessmentPlanID"))
.add(Projections.groupProperty("fkSubindicatorID"))
.add(Projections.groupProperty("InputTitle")))
.addOrder(Order.asc("fkAccademicYearId"))
.addOrder(Order.asc("fkAssessmentPlanID"))
.addOrder(Order.asc("InputTitle"));
List<DashboardSubindicatorSubmission> dashboardSubindicatorSubmissionList = (List<DashboardSubindicatorSubmission>)criteria.list();
session.flush();
transaction.commit();
return dashboardSubindicatorSubmissionList;
I am casting criteria.list() to List<DashboardSubindicatorSubmission> but when i try to do dashboardSubindicatorSubmissionList.get(i) on controller it gives me exception java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to mkcl.accreditation.model.DashboardSubindicatorSubmission.
i come to know that, though i m casting it to List<DashboardSubindicatorSubmission> still its an list of object[] thats why i cant do dashboardSubindicatorSubmissionList.get(i) because it returns me object of DashboardSubindicatorSubmission. (Correct me if i am wrong)
So how can i convert my result into list of DashboardSubindicatorSubmission class?
Does setResultTransformer() helps me in this case?

You have two options. When you use projections, Hibernate doesn't know how to respect each field because it uses the name of each field to build objects and he doesn't know the names yet.
Thus, your first option is to name the fields grouped so that they match the names of object properties. This is necessary even if the string you use in projection is already the name of the object field. Something like:
.add(Projections.groupProperty("fkAccademicYearId"), "fkAccademicYearId") // same value
.add(Projections.groupProperty("fkAssessmentPlanID"), "other") // other value
The second option is to do what you yourself suggested, create your own implementation of ResultTransformer. I reckon this a interesting option if you want to extract other object of this query, as when you make a report.

Related

Spring And Kotlin Query

How can I achieve this query
select *
from table t
where name like '%Ami%'
order by (name = 'Ami') desc, length(col);
(just the sort part)
Using springframework Sort..
What I tried is
Sort.by(Sort.Direction.DESC, "name") // But I need to sort by name = 'Ami'
Sort.by(Sort.Direction.DESC, "name" = 'Ami'") // throws an error
JpaSort.unsafe(Sort.Direction.DESC, "name" = 'Ami'") // throws an error
Looks like the documentation has an example almost identical to your question:
https://docs.spring.io/spring-data/jpa/docs/2.4.5/reference/html/#jpa.query-methods.sorting
However, using Sort together with #Query lets you sneak in
non-path-checked Order instances containing functions within the ORDER
BY clause. This is possible because the Order is appended to the given
query string. By default, Spring Data JPA rejects any Order instance
containing function calls, but you can use JpaSort.unsafe to add
potentially unsafe ordering.

Realm Xamarin LINQ Select

Is there a way to restrict the "columns" returned from a Realm Xamarin LINQ query?
For example, if I have a Customer RealmObject and I want a list of all customer names, do I have to query All<Customer> and then enumerate the results to build the names list? That seems cumbersome and inefficient. I am not seeing anything in the docs. Am I missing something obvious here? Thanks!
You have to remember that Realm is an object based store. In a RDBMS like Sqlite, restricting the return results to a sub-set of "columns" of an "record" makes sense, but in an object store, you would be removing attributes from the original class and thus creating a new dynamic class to then instantiate these new classes as objects.
Thus is you want just a List of strings representing the customer names you can do this:
List<string> names = theRealm.All<Customer>().ToList().Select(customer => customer.Name).ToList();
Note: That you take the Realm.All<> results to a List first and then using a Linq Select "filter" just the property that you want. Using a .Select directly on a RealmResults is not currently supported (v0.80.0).
If you need to return a complex type that is a subset of attributes from the original RealObject, assuming you have a matching POCO, you can use:
var custNames = theRealm.All<Customer>().ToList().Select((Customer c) => new Name() { firstName = c.firstName, lastName = c.lastName } );
Remember, once you convert a RealmResult to a static list of POCOs you do lose the liveliness of using RealmObjects.
Personally I avoid doing this whenever possible as Realm is so fast that using a RealmResult and thus the RealObjects directly is more efficient on processing time and memory overhead then converting those to POCOs everytime you need to new list...

Spring Data Rest - Sort by multiple properties

I have an entity as below
Class Person{
String id;
String name;
String numberOfHands;
}
With Spring Data Rest (Gosling Release Train), I'm able to specify
localhost/Person?sort=name,asc
for sorting name name ascending. Now, in a case where I need to sort by numberOfHands descending and name ascending. I'm able to specify
localhost/Person?sort=numberOfHands,name,asc
But, I'm not able to specify
localhost/Person?sort=numberOfHands,desc,name,asc
Is there a way to specify multiple sort order?
Thanks!
Solution (tl;dr)
When wanting to sort on multiple fields you simply put the sort parameter multiple times in the URI. For example your/uri?sort=name,asc&sort=numberOfHands,desc. Spring Data is then capable of constructing a Pageable object with multiple sorts.
Explanation
There is not really a defined standard on how to submit multiple values for a parameter in a URI. See Correct way to pass multiple values for same parameter name in GET request.
However there is some information in the Java Servlet Spec which hints on how Java servlet containers parse request parameters.
The getParameterValues method returns an array of String objects containing all the parameter values associated with a parameter name. ... - Java Servlet Spec, section 3.1
The sample further in that section states (although it mixes request and body data)
For example, if a request is made with a query string of a=hello and a post body of a=goodbye&a=world, the resulting parameter set would be ordered a=hello, goodbye, world.
This sample shows that when a parameter (a in the example) is presented multiple times the results will be aggregated into a String[].
Here is how to construct the multi Sort object manually/programatically.
Sort sort = Sort.by(
Sort.Order.asc("name"),
Sort.Order.desc("numberOfHands"));
return personRepository.findAll(sort);
Note: This solution does not directly solve the original question asked, but may help visitors that landed on this question while searching for a solution how to sort on multiple properties from a backend perspective / in a somewhat "hardcoded" way. (this solution does not require/take any URI parameters)
When dynamic fields are there then you simply do match with fields and add in sorting list like.
List<Sort.Order> sorts= new ArrayList<>();
if (sort == "name" && sortingOrder.equalsIgnoreCase("DESC")) {
sorts.add(new Sort.Order(Sort.Direction.DESC,"name"));
} else if (sort == "numberOfHands" && sortingOrder.equalsIgnoreCase("DESC")) {
sorts.add(new Sort.Order(Sort.Direction.DESC,"numberOfHands"));
}
return personRepository.findAll(Sort.by(sorts));
If you are using Pagination then directly add in PageRequest Request.
return personRepository.findPersons(PageRequest.of(pageNo, pageSize, Sort.by(sorts)));

Specifying a list of fields in HQL doesn't seem to work

I have the following HQL in Hibernate using Spring MVC.
List<Colour>list=session.createQuery("from Colour order by colourId desc")
.setFirstResult((currentPage-1)*rowsPerPage)
.setMaxResults(rowsPerPage).list();
It works and returns a list of rows from the colour table (actually operates upon the Colour entity (POJO) that I can understand) in Oracle 10g.
What if I need to retrieve a list fields, I'm trying the following.
List<Colour>list=session.createQuery("colourId, colourName, colourHex from Colour order by colourId desc")
.setFirstResult((currentPage-1)*rowsPerPage)
.setMaxResults(rowsPerPage).list();
It ends with an excpetion
java.lang.IllegalArgumentException: node to traverse cannot be null!
In some articles, it was mentioned that the following version of HQL should (or may) work
List<Colour>list=session.createQuery("select colourId, colourName, colourHex from Colour order by colourId desc")
.setFirstResult((currentPage-1)*rowsPerPage)
.setMaxResults(rowsPerPage).list();
but unfortunately, it also didn't work for me. Using the createSQLQuery() method to execute native SQL would work but I want to stick to the createQuery() method with HQL unless it's absolutely necessary. How can I specify a list of fields in HQL?
I agree with yorkw's comment. If you select properties in your query then you cannot ask for a List<Colour> object to be returned from a call to .list().
Instead you should do this
List<Object[]> rows = session.createQuery("select c.colourId, c.colourName, c.colourHex " +
" from Colour c " +
" order by c.colourId desc").list();
Then iterate over the list object and instantiate your objects. Or whatever you need to do.
for ( Object[] row : rows ) {
Long colourId = (Long)row[0];
// ... etc
}
Why don't you try creating a map? Something like this:
SELECT NEW MAP( colour.colourId AS id
, colour.colourName AS name ...)
FROM Colour colour
ORDER BY colour.colourId
I use the alias for Colour "colour" so hibernate knows from which entity is the property I am referencing, I am implying all those properties are from the same entity, if not, then check your referencing!

Entity Framework - Linq - Unable to create a constant value of type ‘System.Object’. Only primitive types

I have a method to build an expression for a linq query for a given type, property, and value. This works wonderfully as long as the property on the type is NOT nullable. Here is the example I am working from (http://www.marcuswhitworth.com/2009/12/dynamic-linq-with-expression-trees) I am calling the Equals method on the property. However I have discovered that the Equals method for Nullable types takes an Object as a parameter instead of the Nullable type. I attempted to use GetValueOrDefault to hide the null values but EF doesn't support that method. As a simple example the following code will throw an error:
decimal? testVal = new decimal?(2100);
var test = (from i in context.Leases where i.AnnualRental.Equals(testVal) select i).ToList();
However if you use == instead of the Equals() method it will work OK. I am not sure how to convert the code to use == instead of Equals() however. Any suggestions will be greatly appreciated.
If you say ==, you generate a BinaryExpression with NodeType as ExpressionType.Equal. http://msdn.microsoft.com/en-us/library/bb361179.aspx
If you say .Equals(x), you generate a MethodCallExpression. The MethodCallExpressions that LinqToEntities may translate into Sql is a limitted list (for example none of your own undecorated methods are in that list). Nullable<T>.Equals(x) is apparently not on that list.
Don't say .Equals(x) to LinqToEntities.

Resources