Question

When I use @Query annotation with select fields, I dont get the entity object back. How can I get the entity object back?

public interface CreditCenterRepository extends JpaRepository<CreditCenter, Long> {
    @Query("SELECT CC.id, CC.loanId, CC.clientId FROM CreditCenter CC")
    List<CreditCenter> findAllIds();
}

When I call this method from my controller, it does not throw any error, but, when I try to iterate it throws classcastexception

List<CreditCenter> objects = findAllIds();
for (CreditCenter cc : objects) { //This line throws ClassCastException
    //some logic
}
Was it helpful?

Solution

Ok It seems that you are using a projection over the entity CreditCenter

@Query("SELECT CC.id, CC.loanId, CC.clientId FROM CreditCenter CC")

My first thought is : Why you dont use something like this.

 @Query("SELECT CC FROM CreditCenter CC")

that will return the list of the entities, however probably you dont want to return all the fields so my second advice is use this query.

@Query("SELECT new package.to.CreditCenter(CC.id, CC.loanId, CC.clientId) FROM CreditCenter CC")

and add a constructor in Creditcenter that support the order and type of parameters. That will work using JPQL and as jpa repos use that it should work.

public class CreditCenter {

 //Member vars
 public CreditCenter (int id, int loadid, int clientid){...}
}

OTHER TIPS

If you want to selectively return parts of the entity, the recommended way to do so in JPA is dedicated DTO types also known as projection classes. For this particular query you'd go ahead with something like this:

class CreditCenterExcerpt {

  private int id, loanId, clientId;

  public CreditCenterExcerpt(int id, int loadid, int clientid) { … }
}

and then use it in a way similarly to the one described by Koitoer.

interface CrediCenterRepository implements Repository<CreditCenter, Integer> {

  @Query("select new ….CreditCenterExcerpt(CC.id, CC.loanId, CC.clientId) from CreditCenter CC")
  List<CreditCenterExcerpt> yourSpecialQueryMethod();
}

The reason I wrote this up as a separate answer is that using the entity type itself has quite a few drawback (hence the recommendation of the separate type in the first place):

The instances returned from a projecting query execution are detached by definition no matter whether the EntityManager is still open or not. By using a separate type for those calls, you don't accidentally create the impression that the object returned was a fully-populated and managed entity instance.

A developer not aware of the projection might just use the instance returned, try to access properties not populated or even try to save the instance in turn and thus wipe out all the properties not loaded in the first place.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top