gpt4 book ai didi

java - 如何在 Hibernate 4 中进行带限制的关联获取?

转载 作者:太空宇宙 更新时间:2023-11-04 14:37:57 24 4
gpt4 key购买 nike

我有根实体Hostel及其单个关联用户所有者

当我获取Hostel实体时,我需要急切地获取用户所有者,但仅获取所有者的3个属性:userIdfirstName,姓氏

此外,在这个查询中,我不需要获取用户所有者的一些关联。它们是:用户实体的头像图像

现在我的条件查询是:

@SuppressWarnings("unchecked")
public void findHostelBy(HostelSearch hs) {
Criteria criteria = currenSession().createCriteria(Hostel.class);

String country = hs.getCountry();

criteria.add(Restrictions.ge("endDate", Calendar.getInstance()));
if (StringUtils.notNullAndEmpty(country)) {
criteria.add(Restrictions.eq("country", country));
}

// making Hostel's associations lazy
criteria.setFetchMode("images", FetchMode.SELECT);
criteria.setFetchMode("requests", FetchMode.SELECT);
criteria.setFetchMode("feedbacks", FetchMode.SELECT);

criteria.setReadOnly(true);
criteria.addOrder(Order.desc("rating"));

// retrieve owner association
criteria = criteria
.createAlias("owner","owner",JoinType.LEFT_OUTER_JOIN)
.setProjection(
Projections.projectionList()
.add(Projections.property("owner.userId"))
.add(Projections.property("owner.firstName"))
.add(Projections.property("owner.lastName")))
.setFetchMode("owner.avatar", FetchMode.SELECT)
.setFetchMode("owner.images", FetchMode.SELECT);

Long count = (Long) criteria
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.setProjection(Projections.rowCount()).uniqueResult();

criteria.setProjection(null);

List<Hostel> hostels = criteria.list();

for (Hostel hostel : hostels) {
User owner = hostel.getOwner();
System.out.println("owner=" + owner);
}
}

//检索所有者关联注释之后,我提取了用户所有者关联。我通过以下方式将 owner 的选择限制为 3 个属性:

Projections.projectionList()
.add(Projections.property("owner.userId"))
.add(Projections.property("owner.firstName"))
.add(Projections.property("owner.lastName")))

然后我将所有者的关联头像和图像设为懒惰:

.setFetchMode("owner.avatar", FetchMode.SELECT)
.setFetchMode("owner.images", FetchMode.SELECT);

我在线遇到异常

List<Hostel> hostels = criteria.list();

异常(exception)是:

Caused by: org.hibernate.TypeMismatchException: Provided id of the wrong type for class com.home.hostme.entity.Image. Expected: class java.lang.Long, got class java.lang.Integer
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:134)
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1092)
at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:1019)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:672)
at org.hibernate.type.EntityType.resolve(EntityType.java:490)
at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:168)
at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:137)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1107)
at org.hibernate.loader.Loader.processResultSet(Loader.java:963)
at org.hibernate.loader.Loader.doQuery(Loader.java:910)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
at org.hibernate.loader.Loader.doList(Loader.java:2522)
at org.hibernate.loader.Loader.doList(Loader.java:2508)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2338)
at org.hibernate.loader.Loader.list(Loader.java:2333)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:124)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1662)
at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:374)
at com.home.hostme.dao.impl.HostelDaoImpl.findHostelBy(HostelDaoImpl.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
... 51 more

Hostel 实体的主键列是 Integer,但 Image 实体的主键是 Long。但我不想急切地从用户所有者处检索头像图像,并且我描述了它。

如何更新我的查询以从用户所有者关联中延迟获取头像图像

此查询从用户所有者关联中获取所有属性,因此我的限制不起作用。

附注如果我不获取用户所有者关联,那么一切正常。

最佳答案

这不是指导 Hibernate 进行 LAZY 获取的方式:

.setFetchMode("owner.avatar", FetchMode.SELECT)

FetchMode.SELECT 用于在单独的选择中检索关联信息

对于 LAZY,您应该设置:

.setFetchMode("owner.avatar", FetchMode.LAZY)

还有很多我不太明白的 idom,例如:

  1. 为什么要创建投影来获取计数:

    Long count = (Long) criteria
    .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
    .setProjection(Projections.rowCount()).uniqueResult();
  2. 然后将投影设置为空

    criteria.setProjection(null);

如果您想要一份有业主但没有任何其他关联的旅馆列表,您只需用以下标记即可:

.setFetchMode("owner.avatar", FetchMode.LAZY)

另一种选择是让所有关联都是 LAZY 并简单地指示在查询的基础上获取什么:

select h
from Hostel h
left join fetch h.owner o

虽然 h.owner.avatar 和 h.owner.images 不被获取是有意义的,但 h.owner.hostel 是实际的旅馆引用,Hibernate 不会为这两者发出新的连接。它知道如何通过单个连接处理双向关联。

关于java - 如何在 Hibernate 4 中进行带限制的关联获取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25332014/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com