代码之家  ›  专栏  ›  技术社区  ›  nonzaprej

带投影的Spring JPA本机查询提供“ConverterNotFoundException”

  •  26
  • nonzaprej  · 技术社区  · 7 年前

    我使用的是Spring JPA,我需要一个本机查询。使用该查询,我只需要从表中获取两个字段,因此我尝试使用 Projections 。它不工作,这是我遇到的错误:

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

    我试图严格按照我链接的页面的说明进行操作,我试图使我的查询非本机查询(顺便说一句,如果我使用投影,我真的需要它是本机查询吗?),但我总是会犯这样的错误。
    如果我使用一个接口,它可以工作,但结果是代理,我真的需要它们是“正常结果”,我可以将其转换为json。

    这是我的代码。实体:

    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @NoArgsConstructor
    @Entity
    @Table(name = "TestTable")
    public class TestTable {
    
        @Id
        @Basic(optional = false)
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        @Column(name = "Id")
        private Integer id;
        @Column(name = "OtherId")
        private String otherId;
        @Column(name = "CreationDate")
        @Temporal(TemporalType.TIMESTAMP)
        private Date creationDate;
        @Column(name = "Type")
        private Integer type;
    }
    

    投影的类别:

    import lombok.Value;
    
    @Value // This annotation fills in the "hashCode" and "equals" methods, plus the all-arguments constructor
    public class IdsOnly {
    
        private final Integer id;
        private final String otherId;
    }
    

    存储库:

    public interface TestTableRepository extends JpaRepository<TestTable, Integer> {
    
        @Query(value = "select Id, OtherId from TestTable where CreationDate > ?1 and Type in (?2)", nativeQuery = true)
        public Collection<IdsOnly> findEntriesAfterDate(Date creationDate, List<Integer> types);
    }
    

    以及尝试获取数据的代码:

    @Autowired
    TestTableRepository ttRepo;
    ...
        Date theDate = ...
        List<Integer> theListOfTypes = ...
        ...
        Collection<IdsOnly> results = ttRepo.findEntriesAfterDate(theDate, theListOfTypes);  
    

    谢谢你的帮助。我真的不明白我做错了什么。

    5 回复  |  直到 7 年前
        1
  •  41
  •   shahaf    6 年前

    使用spring数据,您可以切割中间人并简单地定义

    public interface IdsOnly {
      Integer getId();
      String getOtherId();
    }
    

    并使用本机查询,如;

    @Query(value = "Id, OtherId from TestTable where CreationDate > ?1 and Type in (?2)", nativeQuery = true)
        public Collection<IdsOnly> findEntriesAfterDate(Date creationDate, List<Integer> types);
    

    退房 https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections

        2
  •  15
  •   nonzaprej    6 年前

    查询应使用 constructor expression :

    @Query("select new com.example.IdsOnly(t.id, t.otherId) from TestTable t where t.creationDate > ?1 and t.type in (?2)")
    

    我不知道Lombok,但请确保有一个构造函数将这两个ID作为参数。

        3
  •  6
  •   Montassar El Béhi    7 年前

    JPA 2.1引入了一个有趣的 ConstructorResult 如果要保留功能 出生地的

        4
  •  3
  •   Mohammed Idris Madhura    6 年前

    您可以在repository类中以本机查询方法的返回类型返回对象数组列表(list)。

    @Query(
                value = "SELECT [type],sum([cost]),[currency] FROM [CostDetails] " +
                        "where product_id = ? group by [type],[currency] ",
                nativeQuery = true
        )
        public List<Object[]> getCostDetailsByProduct(Long productId);
    
    for(Object[] obj : objectList){
         String type = (String) obj[0];
         Double cost = (Double) obj[1];
         String currency = (String) obj[2];
         }
    
        5
  •  0
  •   whitefang    4 年前
    @Query(value = "select  isler.saat_dilimi as SAAT, isler.deger as DEGER from isler where isler.id=:id", nativeQuery = true) 
    List<Period> getById(@Param("id") Long id);
    
    
    public interface Period{
        Long getDEGER(); 
    
        Long getSAAT();
    
    }
    

    如上面给出的本机查询示例代码所示,将返回值转换为任何值,如“SAAT”、“DEGER”,然后定义接口“period”,其中包含getDEGER()和getSAAT()。即使我不明白为什么get之后的参数必须是大写的,但在小写的情况下,它不能正常工作。例如,与getDeger()的接口,getSaat()在我的情况下不能正常工作。