2017-02-22 6 views
1

Ich habe eine übergeordnete Entität (Firma) und untergeordnete Entität (Employee), die von einer Beziehung von COMPANY_ID zu vielen Beziehung verbunden sind. Sowohl das Unternehmen als auch der Mitarbeiter haben eine Statusspalte.Hibernate Child Entity Condition Ruft falsche Child

CompanyEntity:

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

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

Mitarbeiter Entity

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

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

Jetzt muss ich alle Unternehmen holen (deren Status in HIGH_PROFIT oder LOW_PROFIT) und die Mitarbeiter (der Status ist DAUER). Ich habe eine Abfrage wie folgt geschrieben.

Abfrage

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(); 

über die Anwendung ausgeführt wird, ich richtig Aufzeichnungen des Unternehmens zu erhalten, wo, wie die Mitarbeiter nicht durch den endgültigen Status gefiltert wird, ist es, alle Kinder sowohl enthält mit CONTRACT und den endgültigen Status.

Auf Hibernate logs Kontrolle, ich sehe 2 Abfragen

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=? 

Ich habe versucht, von Unternehmen Einheit mit @Fetch(FetchMode.SELECT) @Fetch(FetchMode.JOIN) und @Fetch(FetchMode.SUBSELECT) auf Mitarbeiter variabel ausgeführt wird (wie der Code unten), nichts funktionierte.

Ich habe auch versucht, mit Alias ​​auf Kind Entität und die Bedingung auf Kind. Es hat auch nicht funktioniert.

Kann mir jemand helfen, das Kind mit korrektem Status zu filtern?

+0

Für Tri: wie beschrieben sollten Sie entweder auf Service-Level (dh List<EmployeeEntity> fetchEmployeeInPermanentState(CompanyEntity entity) { /* write your query on EmployeeEntity here */ })

oder Sie können Feld auf Ihrem CompanyEntity so etwas wechseln definieren al mit alias hast du sowas wie [this] benutzt (http://stackoverflow.com/a/29457393/1910582)? –

+0

Ja, habe ich. Und es gab mir alle Aufzeichnungen. – Maz

Antwort

1

Sie haben absolut korrekte Ergebnisse erhalten:

Ihre @OneToMany Mapping sollte überhaupt nicht gefiltert werden!

Ihre Anfrage wird an den folgenden Satz umgewandelt: alle CompanyEntities holen, die den Status von ‚HIGH_PROFIT‘ haben und 'LOW_PROFIT UND mindestens einen Mitarbeiter derer Status hat ‚ständigen‘

für Sie etwas haben,

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

Nicht sicher, ob ich das verstehe. Ich kann keinen Filter in der Entity haben, weil ich dieselbe Entity für verschiedene Bedingungen verwenden muss. Ist es nicht? In einem anderen Teil der Anwendung muss ich auch Mitarbeiter von CONTRACT holen. – Maz

+0

können Sie drei weitere Felder definieren: alle Mitarbeiter, Vertragsbediensteten und festangestellten Mitarbeiter. Oder wenn Sie in JAVA8 sind, können Sie einen Liner erstellen, um bestimmte Arten von Mitarbeitern zu erhalten transient listEmployee (String-Typ) {return employees.stream(). Filter (o-> o.status.equals (type)). sammeln (Collectors.toList()); } ' –

+0

Das klingt nicht sehr effizient.Ich habe ähnlichen Code an anderer Stelle in der Anwendung und es funktioniert absolut gut. Ich mache hier etwas falsch und ich finde nicht, was es ist. – Maz