【问题标题】:Spring boot JPA: search entities by field that represent list of embedded objectsSpring boot JPA:按表示嵌入对象列表的字段搜索实体
【发布时间】:2018-01-07 22:26:57
【问题描述】:

我有一个实体Order,里面有选项列表,如下所示:

@Entity
@Table(name = "orders")
public class OrderEntity extends AuditableEntity {
    private Long passengerId;
    private OrderType type;
    private OrderStatus status;
    @ElementCollection()
    @CollectionTable(name = "options", joinColumns = @JoinColumn(name = "order_id"))
    private List<OrderOptionEntity> options = new ArrayList<>(0);
...

我想找到所有订单,匹配指定的选项列表。我正在使用 JpaRepository&lt;OrderEntity, Long&gt; 进行 CRUD 操作。不幸的是,当我添加方法findByOptions 时,像这样:

public interface OrderRepository extends JpaRepository<OrderEntity, Long> {
    List<OrderEntity> findAllByOptions(List<OrderOptionEntity> options);
}

在测试中它抛出

SqlNode 的文本没有引用预期的列数;

所以现在我只需执行findAll() 并手动过滤所有订单。有没有更优雅的方式来获取实体,通过列表中的所有元素进行匹配?

更新: 当我跑步时

@Query("SELECT ord FROM OrderEntity ord WHERE :options MEMBER OF ord.options")
    List<OrderEntity> findAllByOptions(@Param(value = "options") List<OrderOptionEntity> options);

它工作正常,但只有当查询中的 ord.options 和 options 的大小为 1 时,如果更大 - 它会抛出

o.h.engine.jdbc.spi.SqlExceptionHelper:JDBC 中的参数无效 调用:参数索引超出范围:3

生成的SQL是

 /* SELECT
        ord 
    FROM
        OrderEntity ord 
    WHERE
        :options MEMBER OF ord.options */ select
            orderentit0_.id as id1_3_,
            orderentit0_.version as version2_3_,
            orderentit0_.create_time as create_t3_3_,
            orderentit0_.update_time as update_t4_3_,
            orderentit0_.comment as comment5_3_,
            orderentit0_.distance_to_order as distance6_3_,
            orderentit0_.passenger_id as passenge7_3_,
            orderentit0_.price as price8_3_,
            orderentit0_.route_distance as route_di9_3_,
            orderentit0_.status as status10_3_,
            orderentit0_.type as type11_3_ 
        from
            orders orderentit0_ 
        where
            (
                ? , ?
            ) in (
                select
                    options1_.key,
                    options1_.value 
                from
                    options options1_ 
                where
                    orderentit0_.id=options1_.order_id
            )

所有我想要的 - 获取所有订单,其中包含一些选项子集。

【问题讨论】:

  • 可以通过OrderOptionEntity获取OrderEntity。这行得通吗?

标签: spring spring-data-jpa jpql


【解决方案1】:

您可能忘记了查询方法中的 In 关键字。

试试这个

public interface OrderRepository extends JpaRepository<OrderEntity, Long> {

    List<OrderEntity> findAllByOptionsIn(List<OrderOptionEntity> options);

}

看看docs

【讨论】:

  • 谢谢,我读到了。但它抛出了同样的异常:org.springframework.orm.jpa.JpaSystemException:SqlNode 的文本没有引用预期的列数;嵌套异常是 org.hibernate.HibernateException:SqlNode 的文本没有引用预期的列数
  • 您加入的列是否正确joinColumns = @JoinColumn(name = "order_id")
  • 能否调试代码并发布运行的查询?!
  • 很遗憾没有,我的技能还不够,而且 spring.jpa.properties.hibernate.show_sql=true 没有显示出来。
  • OrderOptionEntity@Entity 还是 @Embeddable?如果它是@Embeddable,您可能因为stackoverflow.com/a/3709012/923560 而无法查询它。
猜你喜欢
  • 2016-03-15
  • 2013-04-13
  • 1970-01-01
  • 2020-06-08
  • 1970-01-01
  • 1970-01-01
  • 2020-07-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多