Hibernate 休眠条件以获取第一条记录
我正在尝试解决系统中与分页相关的错误。当用户选择一条记录时,我们使用分页将所有相关记录检索回用户 设置页面maxResults后,DB将检索max记录,但这些记录会被复制并返回到hibernate。然后Hibernate检索重复记录并将剩余记录返回到UI。这导致返回的记录数与页面最大大小不一致 使用hibernate和criteria查询,这是执行的SQL,用于检索所有相关记录Hibernate 休眠条件以获取第一条记录,hibernate,criteria,hibernate-criteria,criteria-api,detachedcriteria,Hibernate,Criteria,Hibernate Criteria,Criteria Api,Detachedcriteria,我正在尝试解决系统中与分页相关的错误。当用户选择一条记录时,我们使用分页将所有相关记录检索回用户 设置页面maxResults后,DB将检索max记录,但这些记录会被复制并返回到hibernate。然后Hibernate检索重复记录并将剩余记录返回到UI。这导致返回的记录数与页面最大大小不一致 使用hibernate和criteria查询,这是执行的SQL,用于检索所有相关记录 select this_.id , this_.created_date , this_.
select
this_.id ,
this_.created_date ,
this_.is_reanalysis_user ,
this_.library ,
this_.state ,
this_.compare_category_id ,
this_.chipkit_id ,
this_.librarykit_id ,
this_.sequencingkit_id ,
this_.templatekit_id ,
this_.templateType ,
ucc.id ,
usrp.user_id ,
usrp.run_parameter_id ,
user1.id ,
user1.templateType ,
utt.VALUE ,
urp.id ,
uki.id as id1_214_5_,
uki.unique_name ,
uki1.id ,
uki1.unique_name ,
ukart.KIT_ID ,
uart.RUN_TYPE ,
uart.RUN_TYPE ,
uki2.id ,
uki2.unique_name ,
uki3.id ,
uki3.unique_name ,
utt.VALUE ,
from
USER this_
left outer join
USER_compare_category ucc
on this_.compare_category_id=ucc.id
inner join
USER_SAVED_RUN_PARAMETER usrp
on this_.id=usrp.user_id
left outer join
USER user1
on usrp.user_id=user1.id
left outer join
USER_TEMPLATE_TYPES utt
on user1.templateType=utt.VALUE
left outer join
USER_RUN_PARAMETER urp
on usrp.run_parameter_id=urp.id
inner join
USER_KITINFO uki
on this_.chipkit_id=uki.id
inner join
USER_KITINFO uki1
on this_.librarykit_id=uki1.id
inner join
USER_KIT_ALLOWED_RUN_TYPES ukart
on uki1.id=ukart.KIT_ID
inner join
USER_ALLOWED_RUN_TYPES uart
on ukart.ALLOWED_RUN_TYPE=uart.RUN_TYPE
inner join
USER_KITINFO uki2
on this_.sequencingkit_id=uki2.id
inner join
USER_KITINFO uki3
on this_.templatekit_id=uki3.id
inner join
USER_TEMPLATE_TYPES utt
on this_.templateType=utt.VALUE
where
utt.VALUE in (
'custom', 'install_seq'
)
and this_.is_reanalysis_user=false
and this_.state in (
'Locked', 'Draft'
)
and utt.VALUE<>'install_seq'
and uki.unique_name='Chip-Chock'
**and usrp.value='amplitude_1'**
and uart.RUN_TYPE in (
'sample'
)
and uki1.unique_name='Blane Library Kit'
and utt.VALUE<>'install_seq'
and uki3.unique_name='Moon reagent Kit'
and uki2.unique_name='Star Seq Kit'
order by
this_.created_date desc
limit 5 offset 0
选择
这个,这个,,
此创建日期,
这是再分析用户,
这个图书馆,
这个州,,
这是比较类别id,
这是芯片组的id,
这是一个图书馆工具包,
这是序列工具包id,
此模板套件id,
这个模板类型,
ucc.id,
usrp.user\u id,
usrp.run\u参数\u id,
user1.id,
user1.templateType,
utt.VALUE,
urp.id,
uki.id为id1_214_5_,
uki.unique_名称,
uki1.id,
uki1.唯一的名称,
ukart.KIT_ID,
uart.RUN_类型,
uart.RUN_类型,
uki2.id,
uki2.唯一的名称,
uki3.id,
uki3.唯一的名称,
utt.VALUE,
从…起
用户本
左外连接
用户\比较\类别ucc
在本例中,比较类别id=ucc.id
内连接
用户\u已保存\u运行\u参数usrp
在这个u.id=usrp.user id上
左外连接
用户用户1
在usrp.user\u id=user1.id上
左外连接
用户模板类型utt
在user1.templateType=utt.VALUE上
左外连接
用户运行参数urp
在usrp.run\u参数上\u id=urp.id
内连接
用户_KITINFO uki
在这个u.chipkit上id=uki.id
内连接
用户_KITINFO uki1
在这个库中,库id=uki1.id
内连接
用户\u套件\u允许\u运行\u类型ukart
关于uki1.id=ukart.KIT\u id
内连接
用户\u允许\u运行\u类型uart
在ukart.ALLOWED\u RUN\u TYPE=uart.RUN\u TYPE上
内连接
用户_KITINFO uki2
在这个目录上,sequencingkit\u id=uki2.id
内连接
用户_KITINFO uki3
在这个u.templatekit上_id=uki3.id
内连接
用户模板类型utt
在这个函数上,templateType=utt.VALUE
哪里
utt.VALUE in(
“自定义”、“安装顺序”
)
这是再分析,用户=false
这个州(
“锁定”,“草稿”
)
和utt.VALUE'install_seq'
还有uki。独一无二的名字是“Chip-Chock”
**和usrp.value='amplitude_1'**
和uart.RUN\u输入(
“样本”
)
和uki1.unique_name='Blane Library Kit'
和utt.VALUE'install_seq'
和uki3。唯一的_name='Moon试剂盒'
和uki2。唯一的_name='Star Seq Kit'
订购人
这是创建日期描述
限制5偏移0
我所观察到的是,具有USER\u SAVED\u RUN\u参数的用户具有@OneToMany关系,因此我看到了重复项,我需要以某种方式添加一个条件usrp.value='Amplication\u 1,以便仅从该表中选择第一条记录
有办法吗?首先,我希望我可以尝试SQL,然后hibernate criteria query。我不知道如何构造查询,但在执行集合的联接获取时使用
setFirstResult
和setMaxResults
会导致问题。通常,在这种情况下,Hibernate不会对查询应用限制,因为这将导致无法正确获取集合。所以Hibernate将获取所有内容并在内存中进行分页,这是非常低效的
如果您使用联接获取,那么您就不走运了。JPA要求托管实体和数据库的状态在事务结束时必须同步,因此仅获取实体的部分集合实际上会删除未获取的元素,这就是JPA不允许这样做的原因。不过,您可以使用Hibernate来执行此操作,但我不推荐使用它,因为它可能会导致删除
因此,为了得到您想要的,您需要编写一个HQL或JPA条件查询,并将数据提取到DTO中。在查询中,您可以选择所需的所有字段,并可以定义您提到的连接条件。如果仍要获取集合,则有其他方法可以实现分页。Blaze Persistence提供了一个简单的API,支持高效的密钥集分页:
关于DTO,我认为这是一个完美的DTO用例
我创建了这个库,以便在JPA模型和自定义接口或抽象类定义的模型之间进行简单的映射,类似于类固醇上的Spring数据投影。其思想是以您喜欢的方式定义目标结构(域模型),并通过JPQL表达式将属性(getter)映射到实体模型
在Blaze持久性实体视图中,您的用例的DTO模型可能如下所示:
@EntityView(User.class)
public interface UserDto {
@IdMapping
Long getId();
Instant getCreatedDate();
@Mapping("savedRunParameters[value = 'aplitude_1']")
RunParameterDto getRunParameter();
@EntityView(RunParameter.class)
interface RunParameterDto {
@IdMapping
Long getId();
}
// Other mappings
}
查询是将实体视图应用于查询的问题,最简单的就是按id进行查询
UserDto a=entityViewManager.find(entityManager,UserDto.class,id)代码>
Spring数据集成允许您像使用Spring数据投影一样使用它: