2013-07-29 4 views
1

Как использовать coalesce или case statement в JPA 2, используя CriteriaBuilderИспользование заявления Coalesce или случая в JPA

Для многих записей initiatedBy будет пустым и как результат employeeName будет нулевым для тех записей. Я хотел бы отобразить Созданная система, если employeeName является нулевым для тех проектов, где initialBy employee имеет значение null в таблице базы данных.

У меня есть следующие отношения в Entities

проекта

@Entity 
@Table(name = "PROJECT") 
public class Project { 

@Id 
@Column(name = "PROJECTID") 
private Long projectId; 
.... 
.... 

@ManyToOne 
@JoinColumn(name = "EMPLOYEENUMBER", referencedColumnName = "EMPLOYEENUMBER") 
private Employee empNumber; 

@ManyToOne 
@JoinColumn(name = "INITIATEDBY", referencedColumnName = "EMPLOYEENUMBER") 
private Employee initiatedBy; 

Сотрудник

@Entity 
@Table(name = "EMPLOYEES") 
public class Employee { 

@Id 
@Column(name = "EMPLOYEENUMBER") 
private String employeeNo; 

@Column(name = "EMPLOYEENAME") 
private String employeeName; 
..... 
..... 

@OneToMany(mappedBy = "empNumber") 
private Set<Project> employeeProject; 

@OneToMany(mappedBy = "initiatedBy") 
private Set<Project> employeeInitiatedBy; 

..... 

в DAOImpl класс У меня есть

CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 
CriteriaQuery<Project> c = cb.createQuery(Project.class); 
Root<Project> emp = c.from(Project.class); 
c.orderBy(cb.desc(emp.get("projectNo"))); 
c.select(emp); 

TypedQuery<Project> q = entityManager.createQuery(c); 

Я попытался с

Coalesce<String> coalesce = cb.coalesce(); 
coalesce.value(emp.<String>get("employeeName")); 
coalesce.value("System Generated"); 

Однако, когда я бегу, я получаю исключение, как

java.lang.IllegalArgumentException: Unable to resolve attribute 
[employeeName] against path 

Любая помощь по этому вопросу является весьма заметным.

ответ

4

Первой проблемой является непонимание в использовании объектов JPA в качестве результата запроса. Когда объекты используются в результате запроса, они зеркалируют состояние базы данных. Замена Employee.empName со значением, отличным от одного в базе данных, противоречит этому.

До определенного момента, который может быть достигнут через CriteriaBuilder.construct. Объекты результатов (которые также могут быть сущностями) создаются с помощью конструктора, который должен принимать все выбранные элементы в качестве аргумента. К сожалению, это не так хорошо сочетается с графом объектов (Project и подключенным Employee в этом случае).

Вторая проблема заключается в том, что в следующем get("employeeName") вызывается для Project, и он не имеет такого атрибута:

Root<Project> emp = c.from(Project.class); 
... 
coalesce.value(emp.<String>get("employeeName")); 

В общем сливаются можно использовать следующим образом (но из-за того, что было сказано выше, это это само по себе не решает проблемы):

CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<String> c = cb.createQuery(String.class); 
Root<Employee> emp = c.from(Employee.class); 

CriteriaBuilder.Coalesce<String> coalesce = cb.coalesce(); 
coalesce.value(emp.<String>get("employeeName")); 
coalesce.value("System Generated"); 
c.select(coalesce); 

TypedQuery<String> q = em.createQuery(c); 
+0

Микко так правильный путь использования '' coalesce' является coalesce.value (эми прибудете ("employeeName".)); '? – user75ponic

+0

Не в этом случае, потому что в данном коде despites это имя emp не относится к Employee. Это корень emp. У Employee есть атрибут employeeName, Project отсутствует. Я добавлю пример использования coalesce для ответа. –

+0

Mikko Что мне нужно для решения моей проблемы? – user75ponic

Смежные вопросы