我正在努力使我的hibernate 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's映射(我希望具有过滤器的多对一映射是热切的)
<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,我不希望这样
是否有一种方法只为指定延迟加载-- DataElement和Filter之间的关系--同时保持FilterAudit和FilterE 228之间的加载渴望?
发布于 2019-10-18 03:06:50
我的建议:不要用急切的抓取。它会导致不一致,有时还会导致奇怪的查询。此外,当您使用急切抓取时,很难对性能进行优化。在上述情况下,我将创建不同的方法来使用一些fetch连接或实体图调用数据库。
我不使用HBM (或其他基于XML的映射)。我使用注释,为什么我不能为您提供XML (HBM似乎已经过时了。)的答案。
我喜欢的方法是使用JPA标准API而不是JPQL。有些人说JPQL更容易理解,但我更喜欢类型安全标准API,它不太容易出错。我更喜欢实体图,因为它们比获取联接更容易动态使用。尽管如此,其他选择也同样有效。
首先,我会设置适合的文章的实体类。(我推断为单向关系。)
@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标准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();
}https://stackoverflow.com/questions/58438341
复制相似问题