2017-09-14 158 views
0

我试图使用jpa自定义查询(不是nativeQuery,因为我想将结果映射到自定义对象),我不知道什么是错的。春季启动JPA“验证失败的查询”JPQL的错误

repository类看起来是这样的:

@Repository 
public interface ChallengeCompletionRepository extends JpaRepository<ChallengeCompletion, Integer>{ 
    List<ChallengeCompletion> findByUser(int uid); 
    List<ChallengeCompletion> findByChallenge(int cid); 
    List<ChallengeCompletion> findByUserAndChallenge(int uid, int cid); 

    @Query(value = "SELECT new com.some.rly.long.package.name.ChallengeScore(user_id, count(id)) " + 
     "FROM ChallengeCompletion " + 
     "WHERE challenge_id = :cid " + 
     "GROUP BY user_id " + 
     "ORDER BY count(id) DESC") 
    List<ChallengeScore> fetchUserScoreForChallenge(@Param("cid") int cid); 
} 

和模型类我想resultl是在外观还是列出这样的:

@Data 
@NoArgsConstructor 
public class ChallengeScore { 

    public ChallengeScore(UUID userId, int score){ 
     this.score = score; 
     this.userId = userId; 
    } 

    private int score; 
    private User user; 

    @JsonIgnore 
    private UUID userId; 

} 

这是ChallengeCompletion型号:

@Entity 
@Data 
@Table(name = "challenge_completions") 
public class ChallengeCompletion extends BaseModel{ 

    @ManyToOne 
    @JsonBackReference 
    private User user; 

    @ManyToOne 
    private Challenge challenge; 

    @ManyToOne 
    private Project project; 

} 

而基本型号是:

@MappedSuperclass 
@Data 
public abstract class BaseModel { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Integer id; 

    @CreationTimestamp 
    private Timestamp createdAt; 

    @UpdateTimestamp 
    private Timestamp updatedAt; 
} 

错误很简单:“验证失败,查询...”。我也觉得有点奇怪,我需要使用我想构建的类的全限定名,但是这可能是由于类不是真实的@Entity而且不会自动加载。

一个完整的堆栈跟踪可以在这里找到:https://pastebin.com/MjP0Xgz4

对于背景下,这是什么查询应该做的是:用户可以多次完成challanges。在ChallengeCompletion中,每个完成都记录为一行。我想获得不同用户(ID)的列表以及他们多久完成一次挑战。

干杯

编辑:多亏了@评论DN1我能得到它找出你的确可以这样做cc.challenge.id如果你不想给一个挑战对象,而是只有一个ID后的工作:

@Query(value = "SELECT new com.energiedienst.smartcity.middleware.module.challenge.model.ChallengeScore(cc.user, count(cc.id)) " + 
     "FROM ChallengeCompletion cc " + 
     "WHERE cc.challenge.id = :cid " + 
     "GROUP BY cc.user " + 
     "ORDER BY count(cc.id) DESC") 
List<ChallengeScore> fetchUserScoreForChallenge(@Param("cid") int cid); 

而且ChallengeScore类现在看起来像:

@Data 
@NoArgsConstructor 
public class ChallengeScore { 

    public ChallengeScore(User user, long score){ 
     this.score = score; 
     this.user = user; 
    } 

    private long score; 
    private User user; 

} 
+0

您是否尝试过使用预测(https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections)或编写自定义实现 – pvpkiran

+0

@pvpkiran,感谢您的答案,不确定您的定制实施意味着什么。据我所知,上述情况应该起作用。我确实有这个问题,我经常需要一个中介类来进行自定义查询,所以我想了解这个问题而不是解决它。错误表示查询有合成错误。 – Tom

+0

你可以把整个堆栈strace。投影是专门用于中间类的情况。我的意思是你可以写一个自定义存储库,并将'ChallengeCompletion'转换为'ChallengeScore' https://stackoverflow.com/questions/43265331/propertyreferenceexception-in-custom-repository/43273248#43273248 – pvpkiran

回答

1

的原因例外是,您正在使用JPQL和JPQLü ses类/字段名称而不是表/列名称(SQL使用什么)。表面上user_idchallenge_id是列名称,您需要将它们更改为使用字段名称。有关详细信息,请参阅this guide