How to add optional parameter in JPQL? - spring

How to use/add optional parameter in JPQL?
#Query(value = "SELECT stud FROM Student stud where stud.name = :studentName AND stud.age IN :studentAgeList")
List<Student> getStudents(
#Param("studentName ") String studentName,
#Param("studentAgeList") List<Integer> studentAgeList
)
How to make studentAgeList parameter in above query ?
I tried below :
#Query(value = "SELECT stud FROM Student stud where stud.name = :studentName AND (:studentAgeList IS NULL OR stud.age IN :studentAgeList))
List<Student> getStudents(
#Param("studentName ") String studentName,
#Param("studentAgeList") List<Integer> studentAgeList
)
But getting error : unexpected AST node:
Tried above but getting error

JPQL does not support optional parameters, you can use overload methods with different queries or criteria API or JPA specifications.
may be get answer here: Set optional parameters in JPQL Query

Related

Spring JPA #Query throws Optional parameter exception with Specification and Param

I'm writing a larger query in JPA and need the pagination, specification and an additional parameter to work in it. I wanna function look like this.
#Query(value = QRY_DATA, countQuery = QRY_DATA_COUNT)
Page<NotificationUserSettingsPageResponse> findAllFrontend(#Nullable Specification<NotificationUserSettings>
spec, Pageable pageable, #Param("user_UUID") String userUUID);
when i try perform query like this i get error
but parameter 'Optional[spec]' not found in annotated query
when i delete last param from query and function it work fine but when i add param JPA try to use Specification like param.
I mention that i need this param to use in join so i can't move it to specification. Query below.
SELECT new pl.notification.dto.response.NotificationUserSettingsPageResponse(s.id,
s.userUUID, n.id,
n.system, n.name, n.category,
b.id, b.businessRule,
CASE WHEN s.id > 0
THEN s.isEmail ELSE 'T' END AS is_email,
CASE WHEN s.id > 0
THEN s.isSMS ELSE 'T' END AS is_sms,
CASE WHEN s.id > 0
THEN s.isPortal ELSE 'T' END AS is_portal)
FROM BusinessRuleConfig b
RIGHT JOIN NotificationConfig n on n.id = b.notificationConfig.id
LEFT JOIN NotificationUserSettings s on s.id = n.id AND s.id = b.id AND s.userUUID =:user_UUID
Seems, you are extend just the JpaRepository for your repository.
You may extend your repo:
#Repository
public interface NotificationUserSettingsPageResponseRepository extends JpaRepository<NotificationUserSettingsPageResponse, Long>, JpaSpecificationExecutor<NotificationUserSettingsPageResponse> {
#Query(value = QRY_DATA, countQuery = QRY_DATA_COUNT)
Page<NotificationUserSettingsPageResponse> findAllFrontend(#Param(value = "user_UUID") String userUUID, Pageable pageable);
}
P.S. And use Pageable argument the last.

How to calculate average on a column with JPA?

I would like to calculate average on a column.
I tried the following:
#Query("SELECT AVG(e.rating) FROM user_rating e WHERE e.route_uid = ?1")
fun averageOfRateings(routeId: UUID): Long
The query works in Sql, however I get the following error when I run the code in Spring Boot.
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException:
user_rating is not mapped [SELECT AVG(e.rating) FROM user_rating e WHERE e.route_uid = ?1]
What would be the right syntax? What is the problem with the mapping of my table?
you must use the entity name, not the table.The same applies for the column name, you must use the field name instead.
I assume your entity is UserRating, so the correct query will be:
#Query("SELECT AVG(e.rating) FROM UserRating e WHERE e.routeUid = ?1")
Or second option specify that is native query:
#Query(value = "SELECT AVG(e.rating) FROM user_rating e WHERE e.route_uid = ?1" , nativeQuery = true)

How to get the data in query(search result of hql)?

I am a novice to use jdbc and I have some problems.
I use hql to search data in MySQL, and the result is Query type. I don't know how to get the data from the "Query".This is my code:
final String hql = "select app.appkey,app.type from " + getClassName() +
"app where app.appkey<>'no-appkey' group by app.type";
Query query = getEntityManager().createQuery(hql);
Thanks a lot.
You have to do the following:
final String hql = "select app.appkey,app.type from " + getClassName() + " app where app.appkey<>'no-appkey' group by app.type";
Query query = getEntityManager().createQuery(hql);
query.list(); //or query.getSingleResult();
query.list() will give a list of results.
query.getSingleResult() will give you a object.
You can check this.
If you are expecting a list of results, so:
List<Object[]> results = query.getResultList();
If you are expect one single result:
Object[] result = query.getSingleResult(); // if more than one result was found, this method will throw a NonUniqueResultException
If column information will be stored in a position of the Object array. Example:
String appKey = (String) result[0];
String appType = (String) result[1];
But work with Object array is not good. Try to use Dto, like explained here.

How to pass Byte value to JPQL in Spring?

I have an Interface wich
extends JpaRepository
I have method in it:
#Query("SELECT a FROM ArticlesEntity a " +
"WHERE ((:approved = 2 ) or (a.approved = :approved)) ")
Page<ArticlesEntity> filterByAllPage(
#Param("approved") Byte approved,
Pageable pageable);
When this method is invoked I have an exeption:
java.lang.IllegalArgumentException: Parameter value [2] did not match expected type [java.lang.Integer (n/a)]
When I change
(:approved = 2 )
to
(:approved is null)
or
#Param("approved") Byte approved
to
#Param("approved") Integer approved
or
"WHERE ((:approved = 2 ) or (a.approved = :approved))"
to
"WHERE (a.approved = :approved) "
it works.
It seems that should be something like
(:approved = (byte) 2 )
or
(:approved=2.byteValue())
but both didn't work also.
Is there any way to use Byte here or it's better to switch to Integer ?
The database is MySQL and it has table "articles" with column "approved" of "TINYINT(1)" type.

generic hql select function given field and param

is this valid HQL?
If not (i assume not since im getting wrong result back). How/can i achieve this generic slect transaction?
String hql = "SELECT * from users Where :searchCriteria = :searchString";
List q = session.createSQLQuery(hql).addEntity(Users.class)
.setParameter("searchField", searchCriteria)
.setParameter("searchString", searchString).list();
Try this hql,
Criteria cr= session.createCriteria(Users.class);
cr.add(Restrictions.eq("searchField", searchCriteria);
cr.add(Restrictions.eq("searchString", searchString);
List<Users> user_data=(List<Users>)cr.list();

Resources