一個真實的生產場景。背景:6個表格:基金,賬戶,期間,期貨權重,持倉,頭寸。休眠,如何在真實世界中加載複雜對象
Fund: The fund information, for example: fund name, total Asset, start time.. etc.
Account: each fund has an account (one to one) to fund.
period: time period (for example: 2000-01-01 to 2000-12-31)
periodweight: at a certain period, the target holding weight.
holding: IBM, Oracle, GE are stock holdings.
position: IBM($3000), oracle($2000), GE($5000)
如果我有一個基金名稱:假基金,其中有一個目標保持爲IBM(30%)中,Oracle(20%),GE(50%)的期間(2000-01-01至2000-12-31),2000-01-01的實際狀況爲10%,10%,80%,2000-01-02爲20%,20%,60%表
Account: id account_Number Fund_id
* 1 0001 10
2 0002 11
Fund: id name other properties...
* 10 fake fund xxx
11 another fake one xxx
period: id start_time end_time fund_id
* 3 2000-01-01 2000-12-31 10
4 2001-01-01 2001-12-31 10
periodWeight: id target_weight holding_id period_id
*11 30% 21 3
*12 20% 22 3
*13 50% 23 3
holding: id name order other properties...
*21 IBM 1 xxx
*22 Oracle 2 xxx
*23 GE 3 xxx
position: id Account_id holding_id date actual_position
1 1 11 2000-01-01 10%
2 1 12 2000-01-01 10%
3 1 13 2000-01-01 80%
4 1 11 2000-01-02 20%
5 1 12 2000-01-02 20%
6 1 13 2000-01-02 60%
的Java類是
Account{
@onetoOne(mappedby="account")
Fund f;
@oneToMany
Set<Position> positions;
}
Fund{
@manyToOne
Account account;
@oneToMany(mappedby="fund")
Set<Period> periods;
}
Period{
@manyToOne
Fund fund;
@oneToMany(mappedby="period")
Set<PeriodWeight> periodWeights;
}
PeriodWeight{
@manyToOne
Period period;
@ManyToOne
Holding holding
}
Holding{
@OneToMany(mappedby="holding")
Set<PeriodWeight> periodWeights;
@OneToMany
Set<Position> positions;
}
Position{
@manyToOne
Account account;
@manyToOne
Holding holding;
}
我想有一個查詢: 基地d日期(2000-01-01)和基金名稱(假基金)。我想創建一個Fund對象,其中包含賬戶和期間(2000-01-01到2000-12-31),期間包含periodWeight,periodWeight包含持有,並且持有包含期權(2000-01-01 )。當沒有這樣的位置時,例如,我查詢2000-01-03和假基金,我想要有結構,只是位置是持有的空集。
如果有數據,hql可以正確加載結構。
select f from Fund f
inner join fetch f.account a
inner join fetch f.period p
inner join fetch p.periodWeight w
inner join fetch w.holding h
inner join fetch h.positions po
where f.name=:name and :date between p.start_date and p.end_date and :date=po.date and po.account= a
問題是當位置表沒有數據時,它返回null。當沒有數據時,我需要一個sql來給我這個結構,它可以加載除了位置之外的所有東西,只需將位置設置爲空即可。
另一個問題是加載這種複雜結構的更好方法是什麼?一個像這樣的hql,或者通過一個hql加載部分結構,然後通過另一個hql加載其他部分?因爲在sql中,你總是一個接一個地加載它們,首先是基金,然後是期限,然後是權重,然後是持有,然後是持倉等。權重需要根據持有訂單進行排序。
select f from Fund f
inner join fetch f.account a
inner join fetch f.period p
inner join fetch p.periodWeight w
inner join fetch w.holding h
left join fetch h.positions po with po.account= a and :date=po.date
where f.name=:name and :date between p.start_date and p.end_date
東西很接近,但是這給我的錯誤,
org.hibernate.hql.ast.QuerySyntaxException: with-clause not allowed on fetched associations; use filters
「問題是什麼時候沒有數據,它會返回null」 - 沒有數據在哪裏?在職位協會? –
是的,當日期的位置表上沒有數據時,我只有2000-01-01和2000-01-02的數據。當我查詢2000-01-03和「假基金」時,它返回資金清單。 – Nan
我想我的第一個問題是,如果我想加載這樣一個對象,我應該把它分成幾個小步驟,而不是一次性加載所有內容?如果我使用太多迷你步驟,我就無法感受到休眠的好處。 – Nan