2017-02-22 11 views
1

У меня есть родительское сущность (компания) и дочернее сущность (Employee), к которому присоединяется одно-много отношений от COMPANY_ID. У компании и сотрудника есть столбец статуса.Сброс настроек дочернего объекта спящего режима Неправильный ребенок

CompanyEntity:

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

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

Сотрудник Entity

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

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

Теперь мне нужно, чтобы извлечь все компании (чей статус в 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(); 

На запуске приложения, я получаю правильные записи компании, где, как работник не фильтруется ПОСТОЯННОГО статуса, он содержит все дети как с КОНТРАКТА и постоянного статуса.

При проверке журналов Hibernate, я вижу 2 запросов выполняются

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

Я попытался с помощью @Fetch(FetchMode.SELECT) @Fetch(FetchMode.JOIN) и @Fetch(FetchMode.SUBSELECT) на сотрудник переменного объекта компании (например, код ниже), ничего не получалось.

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

Я также попытался использовать псевдоним для дочернего объекта и использовать условие для дочернего элемента. Это тоже не сработало.

Может ли кто-нибудь помочь мне в фильтрации ребенка с правильным статусом?

+0

для три- al с псевдонимом вы использовали что-то похожее на [this] (http://stackoverflow.com/a/29457393/1910582)? –

+0

Да, я это сделал. И это дало мне все записи. – Maz

ответ

1

Вы получили абсолютно правильные результаты:

Ваш @OneToMany отображение не должно быть отфильтрованы на всех!

ваш запрос преобразуется в следующее предложение: выборок всех CompanyEntities, которые имеют статус «HIGH_PROFIT» и «LOW_PROFIT» и по крайней мере одного сотрудника тех, имеют статус «перманентный»

для вас есть что-то как описано, вы должны перейти либо к уровню обслуживания (т.е. 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

Не знаю, понимаю ли я это. Я не могу фильтровать жестко закодированные объекты, потому что мне нужно использовать один и тот же объект для разных условий. Не так ли? В какой-то другой части приложения мне нужно также забрать сотрудников КОНТРАКТА. – Maz

+0

, чем вы можете определить еще 3 поля: все сотрудники, сотрудники контрактов и постоянные сотрудники. Или, если вы находитесь в JAVA8, вы можете создать однострочный экземпляр для получения определенного типа временного списка employeeEmployee сотрудника (тип строки) {return employees.stream(). Filter (o -> o.status.equals (type)). сбор (Collectors.toList()); } ' –

+0

Это не очень эффективно.У меня есть аналогичный код в другом месте приложения, и он работает абсолютно нормально. Я делаю что-то неправильно здесь, и я не могу найти, что это такое. – Maz