I have these Postgres tables:

create table deals_new
(
    id                  bigserial primary key,
    slip_id             text,
    deal_type           integer,
    timestamp           timestamp,
    employee_id         bigint
        constraint employee_id_fk
            references common.employees
);

create table twap
(
    id                 bigserial     primary key,
    deal_id            varchar          not null,
    employee_id        bigint
        constraint fk_twap__employee_id
            references common.employees,
    status             integer
);

create table common.employees
(
    id              bigint primary key,
    first_name      varchar(150),
    last_name       varchar(150)
);

Entities:

@Entity
@NoArgsConstructor
@EqualsAndHashCode
@Getter
@Setter
@ToString
@Table(name = "deals_new")
public class DealTwap {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "slip_id")
    private String slipId;
    ...
}

@Entity
@NoArgsConstructor
@Getter
@Setter
@Table(name = "twap")
public class Twap implements Serializable {

    @Id
    @Column(name = "id")
    private long id;

    @Column(name = "deal_id")
    private String dealId;

    @Column(name = "employee_id")
    private Long employeeId;

    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "slip_id", referencedColumnName = "deal_id")
    private List<Deal> deals;
}

@Entity
@Table(name = "employees")
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@Builder
@Getter
@Setter
@ToString
public class Employee {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "first_name")
    private String firstName;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "account_id")
    private Account account;
}

!!NOTE!!! There is not relation between Employee and Twap

I created this JPA repository:

public interface DealsRepository extends JpaRepository<DealTwap, Long> {

    @Query (value =
            "SELECT e.first_name, e.last_name " +
                    "FROM common.deals_new d " +
                    "JOIN common.employees e ON e.id = d.employee_id " +
                    "LEFT OUTER JOIN common.twap t on " +
                    "        t.deal_id = d.slip_id AND " +
                    "        d.timestamp between '11-11-2010' AND '11-11-2011' AND " +
                    "        d.deal_type in (1, 2) " +
                    "OFFSET :offset " +
                    "LIMIT :limit ",
            nativeQuery = true)
    List<ResultDTO> getHistoryAllPairsSearchParam(@Param("offset") int offset,
                                                      @Param("limit") int limit);
}

As you can see I get the result using this Interface:

public interface ResultDTO {
    String getFirstName();
    String getLastName();
}

List<ResultDTO> list = dealsRepository.getHistoryAllPairsSearchParam(...);

    for (ResultDTO item : list) {
        System.out.println("!!!!!!!!!!!!!!! a " + item.getFirstName());
    }

When I run the code I get:

!!!!!!!!!!!!!!! a null
!!!!!!!!!!!!!!! a null
!!!!!!!!!!!!!!! a null
..........

Do you know what could be wrong? I get always null as a result. When I run this query in SQL editor I get proper table with result.


Solution 1:

You are attempting to map native query results to non-entity class. If i am not mistaken resulting column names should match method names. Have you tried setting aliases to the columns like this?

SELECT e.first_name AS firstName, e.last_name AS lastName

Also have you read this Spring Data JPA map the native query result to Non-Entity POJO? It looks pretty similar to your case.

And if that doesn't help it looks as if google has lots of results for how to do it native query result in dto.