2017-04-19 90 views
1

我的代码结构如下所示。Spring Data中的子对象过滤错误JPA查询

文章:

@Entity 
public class NewsArticle{ 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private Long id; 

    [Other class properties such as title, publisher, publishedDate, etc.]   

    @OneToMany(mappedBy = "article") 
    private Set<UserReadNewsArticle> userReadNewsArticles = new HashSet<>(); 

    [Getters and Setters] 
} 

文章由用户阅读:

@Entity 
public class UserReadNewsArticle { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private Long id; 

    private Long readAccountId;  
    private Long readArticleId;   

    @JsonIgnore 
    @ManyToOne 
    private Account account; 

    @JsonIgnore 
    @ManyToOne 
    private NewsArticle article; 

    [Getters and Setters] 


} 

帐户:

@Entity 
public class Account { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private Long id; 

    [Other class properties] 

    @OneToMany(mappedBy = "account") 
    private Set<UserReadNewsArticle> userReadNewsArticles = new HashSet<>(); 

    [Getters and Setters] 
} 

我想在我的NewsArticleRepository查询方法来获取所有阅读新闻用户文章。

public interface NewsArticleRepository extends PagingAndSortingRepository<NewsArticle, Long>{ 

    Collection<NewsArticle> findByUserReadNewsArticlesReadAccountId(Long readAccountId); 

} 

该方法效果很好。但是,我如何编写Spring Data JPA查询/方法来获取“未读用户的新闻文章”。我试过的是以下内容。

Collection<NewsArticle> findByUserReadNewsArticlesReadAccountIdNot(Long readAccountId); 

这个确实会返回其他用户读取的文章列表。但我的要求是获取所有未读的新闻文章。我已经通过Spring Data JPA Documentation,但没有提出一个更容易的灵魂。我怎样才能克服这个问题?或者我做错了什么?

+0

[jpa文档](http://docs.spring.io/spring-data/jpa/docs/1.7.0.M1/reference/htmlsingle/#jpa.query-methods.query-creation)说你可以使用'不在'所以它似乎'收集 findNotInUserReadNewsArticlesByReadAccountId(长readAccountId);'会工作。 – fiskra

+0

@fiskra这将无法正常工作,我想从** NewsArticleRepository **中进行选择,而不是UserReadNewsArticlesRepository。我已经和** NotIn **玩过了,但是还没有能够解决它 – SIRIM4N

+0

除了你的问题..我想你可以删除'readAccountId'和'readArticleId'这两个字段,因为你已经绑定了实体。 – KLHauser

回答

1

您可以通过使用JPQL查询有也一个子查询实现你的结果:

public interface NewsArticleRepository extends PagingAndSortingRepository<NewsArticle, Long> { 

    @Query("SELECT n FROM NewsArticle n WHERE n NOT IN " 
      + "(SELECT ur.article FROM UserReadNewsArticle ur JOIN ur.account a WHERE a.id = :readAccountId)") 
    Collection<NewsArticle> findByUserReadNewsArticlesReadAccountIdNotIn(@Param("readAccountId") Long readAccountId); 

} 

http://localhost:8080/newsArticles/search/findByUserReadNewsArticlesReadAccountIdNotIn?readAccountId=1

因此,首先从当前用户获得读articels,然后从整篇文章列表exlude他们。

我不认为弹簧数据能够让你一样,因为子查询是必要的。如果我错了,有人可以纠正我。

+0

我试过了。虽然 – SIRIM4N

+0

我无法得到它的工作,我添加了一些更多的信息。也许这有帮助。如果没有,发生了什么? – KLHauser

+0

它确实工作。惊人。我以前尝试过的时候肯定犯了错误。非常感谢。 – SIRIM4N