簡體   English   中英

獲取第一條記錄的 Hibernate Criteria

[英]Hibernate Criteria to take the first record

我正在嘗試解決系統中與分頁相關的錯誤。 當用戶選擇一條記錄時,我們使用分頁將所有關聯的記錄檢索回給用戶。

設置頁面 maxResults 后,DB 檢索最大記錄,但它們被復制並返回到休眠狀態。 Hibernate 然后檢索重復項並將剩余的記錄返回給 UI。 這會導致返回的記錄數與頁面最大大小之間不一致。

使用休眠和條件查詢,這是執行檢索所有關聯記錄的 SQL。

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

我觀察到的是 USER WITH USER_SAVED_RUN_PARAMETER 具有 @OneToMany 關系,因此我看到重復,我需要以某種方式添加一個條件usrp.value='amplitude_1 ' 以僅從該表中選擇第一條記錄。

有沒有辦法做到這一點? 首先,我希望我可以嘗試使用 SQL,然后進行休眠條件查詢。

我不知道您如何構造查詢,但是在執行集合的連接提取時使用setFirstResultsetMaxResults會導致問題。 通常,在這種情況下,Hibernate 不會對查詢應用限制,因為這會導致無法正確獲取集合。 因此 Hibernate 會獲取所有內容並在內存中進行分頁,這是非常低效的。

如果你使用連接獲取,你就不走運了。 JPA 要求在事務結束時托管實體和數據庫的狀態必須同步,因此僅獲取實體的部分集合實際上會刪除未獲取的元素,這就是 JPA 不允許這樣做的原因。 但是,您可以使用 Hibernate 執行此操作,但我不推薦它,因為它可能會導致刪除。

所以為了得到你想要的東西,你需要編寫一個 HQL 或 JPA Criteria 查詢並將數據提取到 DTO 中。 在查詢中,您選擇您需要的所有字段,並可以定義您提到的連接條件。 如果您仍然想獲取集合,還有其他方法可以實現分頁。 Blaze-Persistence 提供了一個簡單的 API,支持高效的密鑰集分頁: https : //persistence.blazebit.com/documentation/core/manual/en_US/index.html#pagination

關於 DTO,我認為這是Blaze-Persistence Entity Views的完美用例。

我創建了該庫以允許在 JPA 模型和自定義接口或抽象類定義的模型之間輕松映射,例如類固醇上的 Spring Data Projections。 這個想法是您按照自己喜歡的方式定義目標結構(域模型),並通過 JPQL 表達式將屬性(getter)映射到實體模型。

使用 Blaze-Persistence Entity-Views 的用例的 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 Data 集成允許您幾乎像 Spring Data Projections 一樣使用它: https : //persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM