【问题标题】:How to avoid Spring Data Jpa doing join on simple select?如何避免 Spring Data Jpa 在简单选择上加入?
【发布时间】:2018-03-28 16:21:44
【问题描述】:

我有 @ManyToOne 链接的实体,当我使用条件执行查询时,弹簧使用交叉连接,但我只想在自己的列上进行选择。

案例:

public class Job {

   @Column
   private Long jobId;

   @OneToMany(fetch = FetchType.EAGER)
   @JoinColumn(name="creator", referencedColumnName="uid")
   private User creator;

}

public class User {


   @Column
   private Long uid;

   @Column
   private String name;

}

public Predicate toPredicate(Root<Job> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
    List<Predicate> Predicates=new ArrayList<Predicate>();

   Predicates.add(cb.equal(root.get("creator").get("uid"), 123456));
   query.where(Predicates.toArray(new Predicate[Predicates.size()]));
   return null;
}

我只想创建像“select ... from job where user_id = 123456”这样的查询, 但是 spring 执行类似于“select ... from job m cross join user u where m.creator = u.uid and u.uid = 123456”。

如何避免在多对一链接中加入使用条件,只需在自己的列上选择即可。

【问题讨论】:

  • "Spring" 不使用任何东西。您选择的 JPA 提供程序可以。为什么不告诉人们是哪一个,以及生成的 SQL(以及 JPQL)……都在 JPA 提供者的 LOG 中。 Spring 不是 JPA 提供者。还要发布生成查询的其余 JPA 标准代码。 User 字段不是 @OneToMany ... 只有 Collection/Map 可以这样!!!阅读一些基本的 JPA 文档

标签: java spring jpa


【解决方案1】:

我认为你应该将 fetch type 设置为 lazy : (fetch = FetchType.LAZY), 或删除它,@OneToMany 默认为 LAZY。

这种方式休眠(不是弹簧),会在你的 Job 表上做一个简单的选择查询。但是,如果您将其保留为 EAGER,hibenate 将始终在用户表上使用连接来获取其数据,另一方面,在 LAZY 模式下,只有在您执行 job.getCreator() 时才会触发获取用户数据的查询,但在此如果事务/会话应保持打开状态。

问候,

【讨论】:

  • 除了单值字段不能是@OneToMany ?
  • 是的,绝对的,应该改成OneToOne
【解决方案2】:

创建查询。即

@Query(value = "SELECT * FROM JOB WHERE USER_ID = ?1", nativeQuery = true)
Job getByUserId(Integer userId);

Source

【讨论】:

  • 使用条件,如何获取,Job实体有另一个ManyToOne链接实体,查询条件是动态不固定的。
猜你喜欢
  • 1970-01-01
  • 2019-11-03
  • 1970-01-01
  • 2018-12-24
  • 2021-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-03
相关资源
最近更新 更多