Peter Penzov
Peter Penzov

Reputation: 1680

Create JPA Projection into the same repository

I want to create this JPA Projection:

@Repository
public interface PaymentTransactionRepository extends JpaRepository<PaymentTransactions, Integer>, JpaSpecificationExecutor<PaymentTransactions> {

    @Query(value = "SELECT count(id) as count, status, error_class, error_message, id FROM " +
            " payment_transactions " +
            " WHERE terminal_id = :id AND (created_at > :created_at) "      List<PaymentTransactionsDeclineReasonsDTO> transaction_decline_reasons(@Param("id") Integer transaction_unique_id, @Param("created_at") LocalDateTime created_at);
}

Class based Projection DTO:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder(toBuilder = true)
public class PaymentTransactionsDeclineReasonsDTO {

    private Integer id;

    private Integer count;

    private String status;

    private String error_class; 

    private String error_message;

}

But I get exception

org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [org.plugin.service.PaymentTransactionsDeclineReasonsDTO]

Do you know how I can fix this issue? I suppose that I have to create a separate repository extends JpaRepository<PaymentTransactionsDeclineReasonsDTO, Integer>?

But I would like to use the same repository because I have queries which use the proper entity. Is there some solution?

Upvotes: 0

Views: 180

Answers (1)

Mirko Brandt
Mirko Brandt

Reputation: 475

You should be able to do this with a normal projection as an interface. Here you can find a good tutorial of how to set up an interface based projection. Basically you would convert your PaymentTransactionsDeclineReasonsDTO to an interface and declare the getters you want to access through your projection:

public interface PaymentTransactionsDeclineReasonsDTO {
    int getId();
    int getCount();
    //... and so on
}

This way you can still use the same repository but only get selected properties of your actual class.

Upvotes: 1

Related Questions