如何使用Spring Data JPA按collection属性查找所有匹配项?

时间:2019-06-11 12:45:31

标签: hibernate spring-boot spring-data-jpa spring-data

我有一个实体的集合属性。我需要在数据库中找到包含此字符串的所有记录。就像完整匹配的“ LIKE(%KEYWORD%)”;

Page<Article> findByCategoryIdsContains(String categoryId, Pageable pageable);

但是我在下面遇到了这个错误:

nested exception is java.lang.IllegalArgumentException: 
unknown collection expression type[org.hibernate.query.criteria.internal.path.SingularAttributePath]

我尝试了不同的方式。

此代码可以正常工作:

@Query(value = "SELECT * FROM cms_article WHERE category_ids LIKE %?1%", nativeQuery = true)
Page<Article> findByCategoryIdsLike(String categoryId, Pageable pageable);

但是此代码引发错误:

Page<Article> findByCategoryIdsContains(String categoryId, Pageable pageable);

正确的关键字查询方法是什么?

以下是示例代码:

基本实体:


@Data
@MappedSuperclass
public class BaseEntity implements Serializable {

    @Transient
    private static final long serialVersionUID = 1L;

    @Id
    @Column(columnDefinition = "char(24) comment 'Primary key ID'")
    protected String id;

    @CreatedDate
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "created_time", nullable = false, columnDefinition = "timestamp default current_timestamp comment 'Creation time'")
    protected Date createdTime;

    @LastModifiedDate
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "last_modified_time", nullable = false, columnDefinition = "timestamp default current_timestamp comment 'Last updateed time'")
    protected Date lastModifiedTime;

}

文章实体:


@Data
@Entity
@Table(name = "cms_article")
@org.hibernate.annotations.Table(appliesTo = "cms_article", comment = "Article information table")
@EqualsAndHashCode(callSuper = true)
public class Article extends BaseEntity {

    @Column(columnDefinition = "varchar(120) comment 'Article title'")
    private String title;

    @Column(columnDefinition = "varchar(24) comment 'Article author'")
    private String author;

    @Convert(converter = JpaJsonConverter.class)
    @Column(name = "cover_urls", columnDefinition = "varchar(255) comment 'Article covers'")
    private List<String> coverUrls;

    @Column(columnDefinition = "mediumtext comment 'Article content'")
    private String content;

    @Convert(converter = JpaJsonConverter.class)
    @Column(name = "category_ids", columnDefinition = "varchar(255) comment 'Article category ids'")
    private List<String> categoryIds;
}

我的用于对象到json字符串的自定义属性转换器:


public class JpaJsonConverter implements AttributeConverter<Object, String> {

    @Override
    public String convertToDatabaseColumn(Object object) {
        return JSON.toJSONString(object);
    }

    @Override
    public Object convertToEntityAttribute(String dbData) {
        return JSON.parse(dbData);
    }

}

JPA存储库:

public interface ArticleRepository extends JpaRepository<Article, String> {

    /**
     * Get article page by category id.
     *
     * @param categoryId category id
     * @param pageable   page information
     * @return Article page
     */
    Page<Article> findByCategoryIdsContains(String categoryId, Pageable pageable);

    /**
     * Get article page by category id.
     *
     * @param categoryId category id
     * @param pageable   page information
     * @return Article page
     */
    @Query(value = "SELECT * FROM cms_article WHERE category_ids LIKE %?1%", nativeQuery = true)
    Page<Article> findByCategoryIdsLike(String categoryId, Pageable pageable);

}

以下是数据库记录: enter image description here

3 个答案:

答案 0 :(得分:1)

请尝试使用findByCategoryContainingIgnoreCase方法,而不要使用findByCategoryIdsLike

Highcharts.addEvent(Highcharts.Axis, 'afterBreaks', function() {
    this.series.forEach(s => s.data.forEach(point => point.graphicOverlay = point.graphicOverlay && point.graphicOverlay.destroy()));
});

对于没有@Query的尝试如下。

@Query("Select cmsa from cms_article cmsa where cmsa.category_ids LIKE  %?1%")
Page<Article> findByCategoryContainingIgnoreCase(String categoryId);

答案 1 :(得分:0)

尝试一下:

Page<Article> findByCategoryIdsContainingIgnoreCase(String categoryId, Pageable p);

也许考虑不将Ids以这种方式放入数据库中。您可以有一个单独的表,将categoryIdarticleId匹配。然后,对于属于文章的每个类别都将有一行。

即:

articleId | categoryId
    1     |     1
    1     |     2    
    2     |     1
    2     |     3

答案 2 :(得分:0)

尝试这个

Page<Article> findByCategoryContaining(String categoryId);

引荐文件 "did-fail-load" event

检查上述文档中的内容

表3.方法名称中受支持的关键字