4

coalesce またはcase statementCriteriaBuilder を使用して JPA 2 で使用する方法

多くのレコードでは、initiatedBy は空になり、その結果、それらのレコードの employeeName は null になります。データベーステーブルでinitiatedBy employeeがnullであるプロジェクトに対して、nullの場合はSystem Generatedを表示したいと思います。employeeName

私はエンティティで次の関係を持っています

計画

@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

1 に答える 1

13

最初の問題は、クエリ結果として JPA エンティティを使用する際の誤解の可能性です。クエリの結果としてエンティティが使用されると、エンティティはデータベースの状態を反映します。Employee.empNameデータベースの値以外の値に置き換えることは、それと矛盾します。

CriteriaBuilder.constructを介して達成できる特定のポイントまで。結果オブジェクト (エンティティの場合もあります) は、すべての選択項目を引数として取る必要があるコンストラクターを介して作成されます。Project残念ながら、これはオブジェクト グラフ (およびEmployeeこの場合は接続)とうまく連携しません。

2 番目の問題は、次のようget("employeeName")に for が呼び出されProject、そのような属性がないことです。

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

一般に、coalesce は次のように使用できます (ただし、上記のことから、これだけでは問題は解決しません)。

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);
于 2013-07-29T19:23:23.683 に答える