【问题标题】:How to find all matches by collection attribute using spring data jpa?如何使用spring data jpa按集合属性查找所有匹配项?
【发布时间】:2019-10-25 21:32:50
【问题描述】:

我有一个实体的集合属性。我需要在数据库中查找包含此字符串的所有记录。像一个完全匹配的“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);

}

这里是数据库记录:

【问题讨论】:

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


    【解决方案1】:

    尝试使用 findByCategoryContainingIgnoreCase 方法代替 findByCategoryIdsLike

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

    如果没有@Query,请尝试下面。

    Page<Article> findByCategoryIgnoreCaseContaining(String categoryId);
    

    【讨论】:

    • 您的第一种方式无法获得正确的记录,第二种方式仍然出现同样的错误。
    【解决方案2】:

    试试这个方法:

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

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

    即:

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

    【讨论】:

    • 还是出现这个错误:unknown collection expression type[org.hibernate.query.criteria.internal.path.SingularAttributePath]
    【解决方案3】:

    试试这个

    Page<Article> findByCategoryContaining(String categoryId);
    

    推荐文件 click

    检查上述文件中的内容

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

    【讨论】:

      猜你喜欢
      • 2021-10-10
      • 1970-01-01
      • 2020-06-29
      • 1970-01-01
      • 2020-07-15
      • 1970-01-01
      • 2019-11-20
      • 1970-01-01
      • 2015-04-06
      相关资源
      最近更新 更多