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

spring jpa onetomany关系@查询不工作

  •  0
  • Dan  · 技术社区  · 8 年前

    我试图通过加入feeds表并在其source\u 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]
    

    我曾经尝试过映射一个域名,在这之前我也犯过同样的错误,有人举过一个很好的例子吗?我并没有试图根据feed\u id进行过滤。我是根据source\u id进行过滤,source\u 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 回复  |  直到 8 年前
        1
  •  1
  •   Dan    8 年前

    在对其进行了一些修补之后,我似乎以一种优雅的方式解决了我的问题,并且消除了使用@Query注释的需要。我连接了所有3个模型(源、提要和文章)中的所有关系。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;
        }
    
    }
    

    饲料型号:

    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);
    }