Java: Hibernate Filter & FilterDefs Annotation - java

I would like to clarify few finding.
It's true when define Filter, it's required to define FilterDefs?
There's scenario that i does't required any parameter, because the filter it's self is sufficient.
eg: filterName="filter1" condition="ID in (select id from table1"), filterName="filter2" condition="ID in (select id from table2)"
It's true when define a Filter, filter name should not contain dot "." character?
When I define a class name as filterName, hibernate can't find FilterDefs
eg: filterName="org.my.company.Class1" condition="ID in (select id from table1")
Is the following condition is correct:
filterName="filter3" condition="ID in (select id from table1 where column1 like '%:param1%')"
question: What I'm tries to do?
Answer: I'm using Spring ACL and I want to query all granted entity for given sid. I had create Spring ACL entity object.
My domain and sid is my ACL session query parameter.
Then I'm using my domain name as a filter name so that a would easily enable the required filter
eg: session.enableFilter(myclass.getCanonicalName());
session.createQuery("select count(distinct aoi.id) from AclObjectIdentity aoi join aoi.entries e where ......"
Thanks

Related

Is Spring-GraphQL a good replacement to RSQL?

RSQL is a query language for parametrized filtering of entries in RESTful APIs, meaning I can do something like
curl -X GET http://localhost:8081/api/v1/employee?search=lastName==Doe
where the search query param can take multiple filters -
search=lastName==Doe;firstName==John
which translates to select * from employee where firstName = 'John' and lastName = 'Doe'
In GraphQL I need to define a schema in schema.graphqls which only supports a fixed query as -
type Query {
employeeByLastName(lastName: String): Employee
employeeByFirstName(firstName: String): Employee
}
Is it possible to define a single query in GraphQL that can filter on any field without specifying the field explicitly in the schema?
Something like -
type Query {
filter(params: String[]): Employee
}
Note: I am new to GraphQL, I am following this link

Map sql query result to java object(in Non-Entity class) using spring jpa

I want to assign SQL query result to Java object which is in non-entity class.
My query is counting the number of records in Table A mapped to another Table B.
#Query(value="select count(a.id) from table1 a join table2 b on a.id=b.id group by a.id", nativeQuery=true)
Non-Entity class
public class Sample {
//assign query result to count variable
private long count;
// getters and setters
}
A and B are Entity class, I'm selecting specified columns of Entity A and B and including that columns in Sample.class and sending data as JSON on REST call.
Now my question is to assign count result to count variable.
Thanks in advance
How to do a JPQL query using a "group by" into a projection (Non-Entity-Class)?
Scenario you have two tables: User and User_Role and you want to know how many users in your system has the "public" role and how many have the "admin" role (Any other roles too if present).
For example: I want a query that will let me know there are two users that have "public" role and one user has the "admin" role.
Simplest Example:
#Query("SELECT ur.roleName, count(u.id) from User u left join u.userRole ur group by ur.roleName")
List<Object[]> getCounts();
In this case dealing with the result is more complicated then you typically would want. You would have to iterate over both the list and array of Objects.
Query into a projection Example:
#Query("SELECT new com.skjenco.hibernateSandbox.bean.GroupResultBean(ur.roleName, count(u.id)) from User u left join u.userRole ur group by ur.roleName")
List<GroupResultBean> getCountsToBean();
This would give you a List that is much better to work with.
Code Example: https://github.com/skjenco/hibernateSandbox/blob/master/src/test/java/com/skjenco/hibernateSandbox/repository/UserProjectionExampleTest.java

Spring Data IN clause adds additional brackets

I have a 'Role' table with a 'name' column. I need to get all roles where names are either 'role1' or 'role2'. Role repository method looks like this:
Set<Role> findByNameIsIn(Set<String> roleNames);
My database contains only 'role1'. The request that is generated looks like this:
SELECT ID, NAME FROM ROLE WHERE (NAME IN ((?,?)))
bind => [role1, role2]
Please notice the double brackets around the parameters. Result set is empty. When I try this query manually through the h2 console - no results as well. The following query works:
SELECT ID, NAME FROM ROLE WHERE (NAME IN ('role1', 'role2'))
My set contains two elements exactly. Sets should be supported as a parameter type. See:https://dzone.com/refcardz/core-spring-data
And finally the question: What am I missing?
As Oliver Gierke mentioned - there is a bug opened for this issue in EclipseLink (this is what I'm using as a persistence provider) issue tracker. Since 2011!.. Here is the workaround:
#Query("select r from Role r where r.name in ?1")
Set<Role> findByNameIsIn(Set<String> roleNames);
And here is the valid generated query:
SELECT ID, NAME FROM ROLE WHERE (NAME IN (?,?))
bind => [role1, role2]

Spring Data JPA doesn't specify lower keyword in method names

I need to lowercase all emails when querying my table, but the documentation specifies only method-name-keyowrd for UPPER():
IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstame) = UPPER(?1)
How the LOWER() could be used?
I have debug it and can see that PredicateBuilder doesn't seem to be considering it.
Are you aware if that is a limitation? Or could this be achieved in different way?
As per the Spring JPA reference guide, findXXXByIgnoreCase(...) by default uses UPPER(...) to perform case insensitive search.
To force it to use LOWER keyword we can use a custom query with #Query annotation and specifying SELECT .... LOWER(email)= LOWER(?1).
In my case I have used custom query as below to force it to use LOWER keyword for email column:
#Query("SELECT p from Person p where LOWER(email) = LOWER(?1)")
List<Person> findByEmailIgnoreCase(#Param("email") String email);
and this resulted in creating following query:
Hibernate: select person0_.id as id1_0_, person0_.email as email2_0_, person0_.first_name as first_na3_0_, person0_.last_name as last_nam4_0_ from person person0_ where lower(person0_.email)=lower(?)
This should help the query to use the function index i.e., LOWER(email).
The Spring Data JPA docs say this about case sensitivy of properties:
// Enabling ignoring case for an individual property
List<Person> findByLastnameIgnoreCase(String lastname);
// Enabling ignoring case for all suitable properties
List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);
Using IgnoreCase in your method name will automatically generate a query which is case insensitiv for one or all specified properties.
Otherwise you always have the possibility to specify a custom query for your method by annotating it like this:
#Query("select u from User u")
Stream<User> findAllByCustomQueryAndStream();
By using the #Query annotation you can use the plain old JPQL to query your database.

getting result set into DTO with native SQL Query in Hibernate

I have a query like below
select f.id, s.name, ss.name
from first f
left join second s on f.id = s.id
left join second ss on f.sId = ss.id
If I could use HQL, I would have used HQL constructor syntax to directly populate DTO with the result set.
But, since hibernate doesn't allow left join without having an association in place I have to use the Native SQL Query.
Currently I am looping through the result set in JDBC style and populating DTO objects.
Is there any simpler way to achieve it?
You could maybe use a result transformer. Quoting Hibernate 3.2: Transformers for HQL and SQL:
SQL Transformers
With native sql returning non-entity
beans or Map's is often more useful
instead of basic Object[]. With
result transformers that is now
possible.
List resultWithAliasedBean = s.createSQLQuery(
"SELECT st.name as studentName, co.description as courseDescription " +
"FROM Enrolment e " +
"INNER JOIN Student st on e.studentId=st.studentId " +
"INNER JOIN Course co on e.courseCode=co.courseCode")
.addScalar("studentName")
.addScalar("courseDescription")
.setResultTransformer( Transformers.aliasToBean(StudentDTO.class))
.list();
StudentDTO dto =(StudentDTO) resultWithAliasedBean.get(0);
Tip: the addScalar() calls were
required on HSQLDB to make it match a
property name since it returns column
names in all uppercase (e.g.
"STUDENTNAME"). This could also be
solved with a custom transformer that
search the property names instead of
using exact match - maybe we should
provide a fuzzyAliasToBean() method ;)
References
Hibernate Reference Guide
16.1.5. Returning non-managed entities
Hibernate's Blog
Hibernate 3.2: Transformers for HQL and SQL

Categories

Resources