@Query returning Object instead of entity

邮差的信 提交于 2019-12-21 12:27:16

问题


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
}

回答1:


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){...}
}



回答2:


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.



来源:https://stackoverflow.com/questions/23122846/query-returning-object-instead-of-entity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!