java - 我们如何在 Hibernate (HBM) 中表示一个惰性多对一关系,同时允许在急切模式下引用同一个类?
问题描述
我正在尝试使我的休眠 HBM 文件中的一些多对一关系变得懒惰。具体来说,我有一个DataElement类,它以多对一的关系引用Filter元素,我想让它变得懒惰,同时在应用程序的其他部分保持对Filter的渴望。
我尝试更改我的 HBM 文件,发现lazy="true" 仅在类级别可用
DataElement的映射(我希望带有过滤器的多对一是惰性的)
<hibernate-mapping package="project.me" default-lazy="false" auto-import="false">
<class name="DataElement" table="DATA_ELEMENT">
<id name="id" type="java.lang.Long" column="ID"/>
<many-to-one name="filter" class="project.me.Filter" column="FILTER_ID" cascade="all"/>
</class>
</hibernate-mapping>
FilterAudit的映射(我希望与过滤器的多对一是渴望的)
<hibernate-mapping package="project.me" default-lazy="false" auto-import="false">
<class name="FilterAudit" table="FILTER_AUDIT">
<id name="id" type="java.lang.Long" column="ID"/>
<many-to-one name="filter" class="project.me.Filter" column="FILTER_ID" cascade="all"/>
</class>
</hibernate-mapping>
过滤器的映射
<hibernate-mapping package="project.me" default-lazy="false" auto-import="false">
<class name="Filter" table="FILTERS" lazy="true">
<id name="id" type="java.lang.Long" column="M_ID"/>
<property name="type" type="filterType" column="M_FILTER_TYPE"/>
<many-to-one name="predicate" class="Predicate" column="PRED_ID" unique="true" not-null="true" cascade="all"/>
</class>
</hibernate-mapping>
通过将lazy="true" 放在Filter类的级别,我使应用程序中的所有DTO 都懒惰地加载Filter,我不希望这样
有没有办法只为DataElement和Filter之间的关系指定延迟加载,同时保持FilterAudit和Filter之间的负载渴望?
解决方案
我的建议:不要使用急切的获取。它会导致不一致,有时甚至是奇怪的查询。此外,使用 Eager fetching 时很难优化性能。在提到的情况下,我会创建不同的方法来使用一些获取连接或实体图来调用数据库。
我不使用 HBM(或其他基于 XML 的映射)。我使用注释为什么我不能为您提供 XML 映射的答案(无论如何 HBM 似乎已经过时了)。
我的首选方法是使用 JPA Criteria API 而不是 JPQL。有人说 JPQL 更容易理解,但我更喜欢类型安全的 Criteria API,它不易出错。我更喜欢实体图,因为它们比获取连接更易于动态使用。不过,其他选项也可以。
首先,我会根据Vlad Mihalcea 的文章设置实体类。(我推断出单向关系。)
@Entity
@Table(name = "DATA_ELEMENT")
public class DataElement {
@Id
@GeneratedValue
@Column(name = "ID")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "FILTER_ID")
private Filter filter;
//Constructors, getters and setters...
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof DataElement )) return false;
return id != null && id.equals(((DataElement) o).getId());
}
@Override
public int hashCode() {
return 56;
}
}
FilterAudit
(也)类似FetchType.LAZY
...
然后Filter
(没那么有趣,因为它是单向的)。
@Entity
@Table(name = "FILTERS")
public class Filter {
@Id
@GeneratedValue
@Column(name = "M_ID")
private Long id;
// Other attributes omitted...
//Constructors, getters and setters...
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Filter )) return false;
return id != null && id.equals(((Filter) o).getId());
}
@Override
public int hashCode() {
return 14;
}
}
现在,在这种情况下,使用 JPA Criteria API 和实体图实现了初始化延迟加载(或不初始化)的相关部分。
public DataElement findByIdWithFilter(long id) {
EntityGraph<DatElement> graph = entityManager.createEntityGraph(DataElement.class);
graph.addAttributeNodes("filter");
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<DatElement> cq = cb.createQuery(DatElement.class);
Root<DatElement> root = cq.from(DatElement.class);
cq.where(cb.equal(root.get("id"), id));
TypedQuery<DatElement> typedQuery = entityManager.createQuery(cq);
typedQuery.setHint("javax.persistence.fetchgraph", graph);
DatElement response = null;
try {
response = typedQuery.getSingleResult();
}
catch(NoResultException nre) {}
return response;
}
要检索没有关系的同一类的对象,只需省略实体图。
public DataElement findByIdWithoutFilter(long id) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<DatElement> cq = cb.createQuery(DatElement.class);
Root<DatElement> root = cq.from(DatElement.class);
cq.where(cb.equal(root.get("id"), id));
return entityManager.createQuery(cq).getSingleResult();
}
推荐阅读
- android - 如何在任何操作上保持活动状态(主页按下、后按、概览按下)
- android - Android 上的倒角进度条
- c# - 将 WPF DataGrid 与 Reactivui 一起使用
- javascript - 使用javascript添加到页面的url
- angular - Angular rxjs:保持活动订阅处理http错误
- c - Pthreads 堆栈优先级
- notifications - 低功耗蓝牙 (BLE) GATT 配置文件中的连接和通知
- linux - 重新格式化 ini 字符串
- python - 张量板 - 错误:已启用跟踪 - 如何解决?
- google-chrome-extension - 我应该请求什么权限才能在特定网站列表上显示模式并有短暂的批准延迟