私は次のnamedQueryを持っています
select new test.entity.Emp(COALESCE(k.projectId,'N')
as projectId, k.projectName) from Emp o inner join o.projects k
しかし、私はエラーが発生しています
rIGHT_ROUND_BRACKETを期待して、 '('
NamedQueryでCOALESCE
を処理する方法は?
JPAでnull値を処理する他の方法はありますか?
Coalesceは JPA 2.0 APIでサポート です。
new
コンストラクトはHibernate独自のものであり、必ずしもすべてのJPA実装でサポートされているわけではありません。まず、オブジェクトを作成せずにクエリを試してください。
select COALESCE(k.projectId,'N') as projectId, k.projectName from Emp o inner join o.projects k
角かっこがめちゃくちゃになっているか、余分なエイリアス句があります。これは、ステートメントを適切にインデントすると見やすくなります。
select
new test.entity.Emp(
COALESCE(k.projectId,'N') as projectId,
k.projectName
)
from Emp o inner join o.projects k
代わりにこれを試してください:
select
new test.entity.Emp(
COALESCE(k.projectId,'N'),
k.projectName
)
from Emp o inner join o.projects k
次の簡単な単体テストを試しましたが、成功しました。
@Test
public void coalesceTest() {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("PersistenceUnit");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
DepartmentEmployee employee = new DepartmentEmployee();
EmployeeDepartment department = new EmployeeDepartment();
department.getEmployees().add(employee);
employee.setDepartment(department);
transaction.begin();
try {
entityManager.persist(employee);
entityManager.persist(department);
transaction.commit();
Assert.assertTrue("Employee not persisted", employee.getId() > 0);
Assert.assertTrue("Department not persisted", department.getId() > 0);
} catch (Exception x) {
if(transaction.isActive()) {
transaction.rollback();
}
Assert.fail("Failed to persist: " + x.getMessage());
}
TypedQuery<String> query = entityManager.createQuery("select coalesce(e.name, 'No Name') from EmployeeDepartment d join d.employees e", String.class);
String employeeName = query.getSingleResult();
Assert.assertEquals("Unexpected query result", "No Name", employeeName);
}
DepartmentEmployeeクラス:
@Entity
public class DepartmentEmployee implements Serializable {
@Id
@GeneratedValue
private int id;
private String name;
@ManyToOne
private EmployeeDepartment department;
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public EmployeeDepartment getDepartment() {
return department;
}
public void setDepartment(EmployeeDepartment department) {
this.department = department;
}
}
EmployeeDepartmentクラス:
@Entity
public class EmployeeDepartment implements Serializable {
@Id
@GeneratedValue
private int id;
@OneToMany
private List<DepartmentEmployee> employees;
public EmployeeDepartment() {
employees = new ArrayList<DepartmentEmployee>();
}
public int getId() {
return id;
}
public List<DepartmentEmployee> getEmployees() {
return employees;
}
public void setEmployees(List<DepartmentEmployee> employees) {
this.employees = employees;
}
}
EclipseLink 2.5.0を使用してテスト:
<dependency>
<groupId>org.Eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.5.0</version>
</dependency>