spring jpa onetomany relationship @Query not working

时间:2017-11-26 22:31:16

标签: java spring spring-boot spring-data-jpa jpql

我试图通过加入feed表并过滤它的source_id字段来提取所有文章记录。

我的存储库:

package com.infostream.repositories;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;

import com.infostream.models.Article;
import java.lang.String;

public interface ArticleRepositoryImpl extends PagingAndSortingRepository<Article, Long> {
    Page<Article> findAll(Pageable pageRequest);

    Page<Article> findByFeedId(String feedId, Pageable pageable);

    @Query("select a from Article a join Feed f where f.source_id = ?1");
    Page<Article> findBySourceId(String sourceId, Pageable pageable);
}

Feed模型:

package com.infostream.models;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.infostream.serializers.JsonDateSerializer;

@Entity
@Table(name="feeds")
public class Feed extends Base {

    @Column(name = "source_id", nullable = false)
    private String sourceId;

    @Column(name = "category_id", nullable = false)
    private String categoryId;

    @NotNull
    @Column(columnDefinition="text")
    private String url;

    @Column(name = "last_visited")
    private Date lastVisited;

    public Feed() {
    }

    public Feed(String sourceId, String categoryId, String url) {
        this.sourceId = sourceId;
        this.categoryId = categoryId;
        this.url = url;
    }

    @JsonSerialize(using = JsonDateSerializer.class)
    public Date getLastVisited() {
        return lastVisited;
    }

    public void setLastVisited(Date lastVisited) {
        this.lastVisited = lastVisited;
    }

    public String getSourceId() {
        return sourceId;
    }

    public void setSourceId(String sourceId) {
        this.sourceId = sourceId;
    }

    public String getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(String categoryId) {
        this.categoryId = categoryId;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }



}

文章模型:

package com.infostream.models;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;

@Entity
@Table(name = "articles")
public class Article extends Base {

    public Article() {

    }

    public Article(String feedId, String title, String description, String url) {
        this.feedId = feedId;
        this.title = title;
        this.description = description;
        this.url = url;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getImgUrl() {
        return imgUrl;
    }

    public void setImgUrl(String imgUrl) {
        this.imgUrl = imgUrl;
    }

    public String getFeedId() {
        return feedId;
    }

    public void setFeedId(String feedId) {
        this.feedId = feedId;
    }

    @Column(name = "feed_id", nullable = false)
    private String feedId;

    @NotNull
    @Column(columnDefinition="text")
    private String title;

    @Column(name = "img_url", columnDefinition="text")
    private String imgUrl;

    @Column(columnDefinition="text")
    private String description;

    @NotNull
    @Column(columnDefinition="text")
    private String url;

    @Override
    public String toString() {
        return "Article [feedId=" + feedId + ", title=" + title + ", imgUrl=" + imgUrl + ", description=" + description
                + ", url=" + url + "]";
    }   


}

我得到的错误:

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join! [select a from com.infostream.models.Article a join Feed f where f.source_id = ?1]

我尝试过映射OneToMany之前给我带来了同样的错误,有没有人有一个很好的例子显示它?我不是要尝试过滤feed_id。我在source_id上​​过滤,这是feed表上的一个字段。

基本上,我想要实现的只是抽象这个原始的sql查询到spring和hibernates的做事方式:

select a.* from articles as a join feeds as f on(a.feed_id = f.id) where f.source_id = 'some_source_id';

1 个答案:

答案 0 :(得分:0)

经过一些修修补补后,我似乎已经以优雅的方式解决了我的问题,并且无需使用@Query注释。我连接了所有3个模型(Source,Feed和Article)中的所有关系。 OneToMany和ManyToOne,然后能够使用findBy *生成的一个spring方法,它的工作原理。如果有人需要参考,下面是所有修改过的文件。

来源模型:

package com.infostream.models;

import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;

import org.hibernate.validator.constraints.NotEmpty;

@Entity
@Table(name="sources")
public class Source extends Base {

    @NotNull
    @NotEmpty
    private String name;

    @OneToMany(mappedBy = "source", cascade = CascadeType.ALL)
    private Set<Feed> feeds;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Source() {

    }

    public Source(String name) {
        this.name = name;
    }

}

Feed模型:

package com.infostream.models;

import java.util.Date;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.infostream.serializers.JsonDateSerializer;

@Entity
@Table(name="feeds")
public class Feed extends Base {

    @ManyToOne
    @JoinColumn(name = "source_id", nullable = false)
    private Source source;


    @Column(name = "category_id", nullable = false)
    private String categoryId;

    @NotNull
    @Column(columnDefinition="text")
    private String url;

    @Column(name = "last_visited")
    private Date lastVisited;

    @OneToMany(mappedBy = "feed", cascade = CascadeType.ALL)
    private Set<Article> articles;

    public Feed() {
    }

    public Feed(Source source, String categoryId, String url) {
        this.source = source;
        this.categoryId = categoryId;
        this.url = url;
    }

    @JsonSerialize(using = JsonDateSerializer.class)
    public Date getLastVisited() {
        return lastVisited;
    }

    public void setLastVisited(Date lastVisited) {
        this.lastVisited = lastVisited;
    }

    public String getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(String categoryId) {
        this.categoryId = categoryId;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }



}

文章模型:

package com.infostream.models;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;

@Entity
@Table(name = "articles")
public class Article extends Base {

    public Article() {

    }

    public Article(Feed feed, String title, String description, String url) {
        this.feed = feed;
        this.title = title;
        this.description = description;
        this.url = url;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getImgUrl() {
        return imgUrl;
    }

    public void setImgUrl(String imgUrl) {
        this.imgUrl = imgUrl;
    }

    @ManyToOne
    @JoinColumn(name = "feed_id", nullable = false)
    private Feed feed;

    @NotNull
    @Column(columnDefinition="text")
    private String title;

    @Column(name = "img_url", columnDefinition="text")
    private String imgUrl;

    @Column(columnDefinition="text")
    private String description;

    @NotNull
    @Column(columnDefinition="text")
    private String url;

}

ArticleRepository文件

package com.infostream.repositories;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;

import com.infostream.models.Article;
import java.lang.String;

public interface ArticleRepositoryImpl extends PagingAndSortingRepository<Article, Long> {
    Page<Article> findAll(Pageable pageRequest);

    Page<Article> findByFeedId(String feedId, Pageable pageable);

    Page<Article> findByFeed_sourceId(String sourceId, Pageable pageable);
}
相关问题