按需加载

9rygscc1  于 2021-07-05  发布在  Java
关注(0)|答案(2)|浏览(254)

我提出一个问题:

String query = "SELECT DISTINCT a FROM A a FETCH ALL PROPERTIES " +
        "JOIN a.Bs AS b " +
        "JOIN b.Cs AS c WHERE c = :c";
Query q = DAO.getSession().createQuery(query);
q.setParameter("c", c);
return q.list();

尽管我说过 FETCH ALL PROPERTIES 在a上,当我访问a拥有的所有集合时,仍然需要加载它们,因此并不急于加载。它们被定义为延迟加载,这是我想要的默认行为,但这是一个例外:我希望它们现在就被加载。我试过交换 JOIN 为了 LEFT OUTER JOIN 为了刺激hibernate加载它们,我试着设置 q.setFetchMode("a", FetchMode.EAGER) ,但查询时不存在。
as的列表相当长,而且它们有相当多的集合,因此将其作为一个n+1查询非常慢(大约10秒,而不是在一个查询中以亚秒的速度进行)。我更喜欢一个查询,并加载所有必要的一次去。有什么建议吗?
还有一个小问题:如果我把 "JOIN b.Cs AS c WHERE c = :c"; 符合 "WHERE :c IN b.Cs"; ,我得到一个sql异常:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '))' at line 1

它所指的双参数是“and('151000000-0000'in(.))”,其中151000000-0000是 c . 你知道为什么我这样做的时候会出现这个错误吗?和我加入b.cs的时候没有相比?
根据请求更新,下面是我用于Map的方法。b和c的设计非常相似:

@Entity
@Table(name = "tblA")
public class A  {
  @Id
  String AId;

  @Column(name = "shortName", length = 12, nullable = false)
  String shortName;

  @OneToMany(fetch=FetchType.LAZY, mappedBy="theA")
  private Set<B> Bs;

  @OneToMany(fetch=FetchType.LAZY, mappedBy="theA")
  private Set<D> Ds;

  @OneToMany(fetch=FetchType.LAZY, mappedBy="theA")
  private Set<E> Es;

  @OneToMany(fetch=FetchType.LAZY, mappedBy="theA")
  private Set<F> Fs;
}

b、d、e和f中的thea定义如下:

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "AId", nullable = true)
@ForeignKey(name="FK_KategoriID")
private A theA;

干杯
尼克

wvt8vs2t

wvt8vs2t1#

FETCH ALL PROPERTIES 仅适用于惰性属性(其中属性是字符串、整数等),而不是一到多个关联(即集合)
请参阅有关获取策略的简短入门

hujrc8aj

hujrc8aj2#

fetch all properties 不是你想要的;它用于告诉hibernate您希望它获取单值的延迟加载属性。详情在这里。
您需要指定 join fetch 在您的查询中:

SELECT DISTINCT a FROM A a
  LEFT JOIN FETCH a.Bs AS b
  LEFT JOIN FETCH b.Cs AS c
 WHERE c = :c

至于奖金问题, WHERE :c IN b.Cs 是非法语法。取决于你的 C 是Map的,您可能要查看 elements() 而不是功能。

相关问题