Hibernate query method requires all columns being returned in query?

580 Views Asked by At

I have written a native query for a repository method that groups by specific columns.

I can't group by id as that will break the grouping.

      @Query(nativeQuery = true, value = "SELECT description, model_year, take_rate, number " +
          "FROM foo f " +
          "INNER JOIN bar b " +
          "ON b.cycle_plan_code = b.cycle_plan_code " +
          "WHERE b.programme = :programme " +
          "AND b.build_event = :buildEvent " +
          "AND f.vehicle_line = :vehicleLine " +
          "GROUP BY description, take_rate, model_year, number")
  List<FooEntity> findAllFooByBar(@Param("vehicleLine") String vehicleLine, @Param("programme") String programme,
                                          @Param("buildEvent") String buildEvent);

My entity has an @Id column and some others

@Table(name = "foos")
public class FooEntity {

  @Id
  private Long id;

  @Column(name = "cycle_plan_code")
  private String cyclePlanCode;

  @Column(name = "model_year")
  private String year;

  @Column(name = "vehicle_line", nullable = true)
  private String vehicleLine;

  @Column(name = "number")
  private Integer number;

  @Column(name = "description")
  private String description;

  @Column(name = "take_rate")
  private double takeRate;

}

When accessing the repository method it throws a hibernate

o.h.engine.jdbc.spi.SqlExceptionHelper   : Column 'id' not found.

I tried to hack it by adding this to the select clause

SELECT 0 as id

This progresses, however it then complains the query doesn't return the other columns for the entity vehicle_line , model_year I had to add them all to the query to make it work.

I tried the nullable = true flag in the annotation but that didn't allow me to omit columns from the select clause.

How can I return entities with only some of the columns being returned that I am interested in?

1

There are 1 best solutions below

2
On BEST ANSWER

Try using Projections: Declare an interface with the getters of the fields you want:

public interface SubFooEntity{
String getDescription();
String getModelYear();
Double getTakeRate();
Integers getNumber(); 
}

Change repository method to below:

 @Query("SELECT description, modelYear, takeRate, number " +
      "FROM foo f " +
      "INNER JOIN bar b " +
      "ON b.cyclePlanCode = b.cyclePlanCode " +
      "WHERE b.programme = :programme " +
      "AND b.build_event = :buildEvent " +
      "AND f.vehicle_line = :vehicleLine " +
      "GROUP BY description, takeRate, modelYear, number")


List<SubFooEntity> findAllFooByBar(@Param("vehicleLine") String vehicleLine, @Param("programme") String programme,
                                          @Param("buildEvent") String buildEvent);

More on it here: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections