Search code examples
javahibernatejpajpqlentitymanager

"select new constructor" query returns java.lang.Object instead of instance of constructors class


var toShow is instance of pure java.lang.Object, and the only way it works if I cast it to FactionProjection, and I do not think that's the proper way. My method:

    public FactionProjection getFactionById(int id){
    Query query = entityManager.createQuery(
        "SELECT new com.gamerecords.result_recorder.model.projection.FactionProjection(f.name)" +
        "FROM Faction f WHERE f.id = :id",FactionProjection.class)
        .setParameter("id",id);
    var toShow =  query.getSingleResult();
    return toShow;

}

constructor:

    public FactionProjection(String name) {
    this.name = name;
}

what I have tried:

  • changing second argument of .createQuery to Faction.class, or deleting it
  • changing method .getSingleResult() to .getResultList()

Working code I have now is:

    public FactionProjection getFactionById(int id){
        Query query = entityManager.createQuery(
            "SELECT new com.gamerecords.result_recorder.model.projection.FactionProjection(f.name)" +
                " FROM Faction f WHERE f.id = :id",FactionProjection.class)
            .setParameter("id",id);
        var toShow =  (FactionProjection)query.getSingleResult();
        return toShow;
      }

I have seen many examples of "select new constructor" expression, and there was no need for casting, which makes me think I'm making a mistake here.


Solution

  • The normal Query API does not return the exact type of Object you expect and you need to cast. Query#getSingleResult() returns an Object. You can use TypedQuery<T> instead:

    TypedQuery<FactionProjection> query;
    var result= query.getSingleResult();