2017-02-22 9 views
1

私は、COMPANY_IDによって1対多数の関係によって結合されている親エンティティ(会社)と子エンティティ(従業員)を持っています。会社と従業員の両方にステータス欄があります。Hibernate子エンティティ条件のフェッチ正しくない子

CompanyEntity:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "company") 
private List<Employee> employees = new ArrayList<>(); 

@Column(name = "COMPANY_STATUS") 
private String status; 

従業員エンティティ

@ManyToOne(fetch = FetchType.LAZY) 
@JoinColumn(name = "COMPANY_ID", nullable = false) 
private Company company; 

@Column(name = "EMPLOYEE_STATUS") 
private String status; 

今は状況がPERMANENTが誰であるか((その状態HIGH_PROFITまたはLOW_PROFITである)すべての企業と従業員をフェッチする必要があります)。私は以下のような質問を書いた。アプリケーションを実行するには

クエリ

Criteria criteria = getSession().createCriteria(Company.class); 
    List<String> statusList = new ArrayList<>(); 
    statusList.add("HIGH_PROFIT"); 
    statusList.add("LOW_PROFIT"); 
    criteria.add(Restrictions.in("status", statusList)).createCriteria("employees").add(Restrictions.eq("status", "PERMANENT")); 
    criteria.list(); 

、私は従業員がPERMANENT状況によってフィルタリングされていないとして正しい会社の記録を取得、それは契約とPERMANENT状態の両方で、すべての子どもが含まれています。

休止状態のログを確認するには、私は(下記のコードのような)会社のエンティティの従業員変数に@Fetch(FetchMode.SELECT) @Fetch(FetchMode.JOIN)@Fetch(FetchMode.SUBSELECT)を使用してみました

1. select this_.id as id1_3_2_, this_.COMPANY_NAME as COMPANY_NAME2_3_2_, this_.COMPANY_STATUS as COMPANY_STATUS3_3_2_, employ1_.id as id1_5_0_, employ1_.EMPLOYEE_STATUS as EMPLOYEE_STA4_5_0_ from COMPANY this_ inner join EMPLOYEE employ1_ on this_.id=employ1_.COMPANY_ID where this_.COMPANY_STATUS in (?, ?) and employ1_.EMPLOYEE_STATUS_ID=? 

2. select employ0_.COMPANY_ID as COMPANY_ID5_5_0_, employ0_.id as id1_5_0_, employ0_.EMPLOYEE_STATUS as EMPLOYEE_STA4_5_1_ from EMPLOYEE employ0_ where employ0_.COMPANY_ID=? 

を実行されている2つのクエリを参照してください、何も働きました。

@OneToMany(cascade = CascadeType.ALL, mappedBy = "company") 
    @Fetch(FetchMode.SELECT) 
    private List<Employee> employees = new ArrayList<>(); 

私はまた、子エンティティでエイリアスを使用して、子供の条件を使用してみました。それはどちらもうまくいかなかった。

正しい状態の子供をフィルタリングするのに役立つ人がいますか?

+0

TRIのためのあなたは[this](http://stackoverflow.com/a/29457393/1910582)と同様のものを使用しましたか? –

+0

はい、私はしました。そしてそれは私にすべての記録を与えました。 – Maz

答えて

1

あなたは絶対に正しい結果を受けています

あなた@OneToManyマッピングがすべてで濾過するべきではありません!

クエリは、次の文に変換され

「HIGH_PROFIT」と「LOW_PROFIT」ANDそれらの少なくとも一つの従業員があるのステータスを持つすべてのCompanyEntitiesを取得状況「パーマ」

あなたが何かを持っているため説明のように、あなたは(すなわちList<EmployeeEntity> fetchEmployeeInPermanentState(CompanyEntity entity) { /* write your query on EmployeeEntity here */ })サービスレベル

のいずれかに切り替える必要があります。また、そのようなあなたのCompanyEntityの何かにフィールドを定義することができます。

@Filter(condition = "status = 'PERMANENT'") 
@OneToMany(cascade = CascadeType.ALL, mappedBy = "company") 
private List<Employee> permanentEmployees = new ArrayList<>(); 
+0

私がこれを理解しているかわかりません。異なるエンティティで同じエンティティを使用する必要があるため、エンティティでフィルタをハードコードすることはできません。ではない?申請の他の部分では、私はCONTRACTの従業員も雇う必要があります。 – Maz

+0

より3つのフィールド(すべての従業員、契約従業員、常勤従業員)を定義することができます。また、JAVA8の場合、特定の種類の従業員の一時的なlistEmployee(String型){return employees.stream()。filter(o-> o.status.equals(type))をフェッチするための1行を作成できます。コレクション(Collectors.toList()); } ' –

+0

それは非常に効率的に聞こえません。私はアプリケーションのどこかで同様のコードを持っており、それは絶対にうまく動作します。私はここで何か間違っていると私はそれが何であるかを見つけることができません。 – Maz

関連する問題