Springboot JPA #Query Rest Giving PersistentEntity must not be null - spring-boot

I am trying to put together a simple rest service with springboot 1.4.3. I have it up and running with simple queries like findByRecid, however when I try to do a #Query statement on that same entity, I get the below error message
{"cause":null,"message":"PersistentEntity must not be null!"}
Further, if I use a fully qualified name for the entity in the query, Intellij tells me that the class isn't an entity, even though it's marked with #Entity and works with the standard springboot queries. Please assist if possible - I've been trying to figure this one out for days. Below is the query for your reference
#Query("SELECT new com.test.domain.ReceivableBeans.RecAgeBucketGroupAmountSum(r.agebucket, sum(r.amount)) from com.test.domain.Receivable as r GROUP BY r.agebucket")
List<com.test.domain.ReceivableBeans.RecAgeBucketGroupAmountSum> recByAgeBucket();

Try:
#Query("select new ReceivableStats(r.agebucket, sum(r.amount)) from Receivable r group by r.agebucket")
List< ReceivableStats> recByAgeBucket();
or name your aliases in the query, e.g.
sum(r.amount) as amount
and have your method return an Object[].

Related

Native Query in spring boot JPA

I'm using spring boot 2.6 and spring boot JPA version 2.6.4. I was interested in pull last five records from mysql table by using next query
#Query(value="SELECT * FROM produit p ORDER BY p.id DESC LIMIT 5")
public Collection getProduit();
Normally in the #Query block, i need to add the nativeQuery = true after the value property but the nativeQuery attribute is not defined. What am i missing?
Please help, already 5 hours searching on this.
When using a native query you need to define a mapping of the values to for example your own type. You could use interface based projections when you only need to read data see interface based projections. Then your could would look like
#Query(nativeQuery=true, value="SELECT * FROM produit p ORDER BY p.id DESC LIMIT 5")
Set<Projection> getProduit();
Another thing to check would be what import is used for the #Query annotation, maybe it is the wrong one.

Expose custom query in Spring Boot Rest API with multiple joins

I have an Spring REST Api and a MySQL Database, now I would like to expose the result of an custom query with multiple joins.
I have tried multiple suggestions that I found online but none of them were working for me so far.
What I want to do is something like a read only DTO that has all the fields of my custom query so that in the end I have one api page exposing the DTO data as JSON so my client (Angular) can read the data from there.
I already tried to:
create an #RestController with an injected EntityManager that executes a NativeQuery and then populates the DTO with the returned data but since my DTO is no Entity I get an Hibernate Mapping Exception
create a custom Repository and its Impl but with a similar outcome
place the Query inside an existing #Entity that is part of the Query statement
What am I missing here? Do I have to annotate my DTO maybe? Cuttently it's just a POJO, I think the #Entity annotation is not the right thing here since I don't want a Table created from my DTO.
Fixed it by letting the Query return an Array of type Object and afterwards mapping it to the DTO Constructor.

How Spring data jpa #Query annotation works

I am new to both Spring data and JPA. I am curious how the query annotation works. Like in my scenario I need all the userIds of an organization. So this is what i did:
#Query("select o.userId from User o where o.orgId = :orgId")
List <Integer> findUserIdsByOrgId(#Param("orgId")int orgId);
The above statement works fine. I get a list of user Ids. The problem is when I alter the query to search for the User
#Query("select o from User o where o.orgId = :orgId")
List <Integer> findUserIdsByOrgId(#Param("orgId")int orgId);
As I remove userId from o.userId the whole object is returned and not an Integer.
My assumption is that an error should be thrown if the return type is not matched to the one in the query.
The thing is that generics in Java are removed in runtime.
Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
So Spring cannot make a check for generic type and trusts you that you don't mismatch type. Of course, if you return Integer instead of User (without generics) then Spring would throw an error.
Change the return type from List<Integer> to List<User> and it should work fine.

How to limit the results of a Spring Repository with custom query

I am using a Spring repository to query a database, but because of the nature of my application I need to use a custom #Query in order to JOIN FETCH lazy collections.
This process works fine, but now I need to limit the result to a single record. I understand that Spring has the notion of findFirst or findTop1 in the method names, but this does not appear to work when you have a custom query.
How can I use a custom query and limit the result to 1 record when using a Spring repository?
you need to pass a Pageable param in your query method
#Query("select e from Entity e LEFT JOIN FETCH e.list")
public Page<Entity> find(Pageable pageable);
and call the method passing the object
repository.find(new PageRequest(0, 1));

Pageable sorting not working for Spring Data JPA when using named queries

I got to grips with using Spring Data JPA however I stumbled upon an issue, searched all the net but still didn't find an answer. I got the repository working and even the paging and sorting. However, it seems that when I do the same, but specifying a named query in the #Query annotation, rather than letting Spring generate the query at runtime, the sortable part of the Pageable object is completely ignored. I can confirm this as the query generated by Hibernate does not have an "ORDER BY" clause in the latter case.
public interface TransactionRepository extends JpaRepository<Transaction, Long>
{
#Query(name = "Transaction.findParentTransactionsByStatus", countName = "Transaction.findCountParentTransactionsByStatus")
public Page<Transaction> findParentTransactionsByStatus(#Param(value = "status") TransactionStatus status, Pageable pageable);
Any ideas?
Can you post the actual HQL from your named query Transaction.findParentTransactionsByStatus?
The reason I am asking is, I encountered this same issue and it was because I had an extra end parenthesis ")" in my HQL. For some reason, it was being accepted as a valid HQL, but when passing the sort via Pageable, it was not including the sort column. My solution was to remove that extra parenthesis and it worked

Resources