COALESCE in JPA namedQuery

大兔子大兔子 提交于 2019-11-28 03:29:26

问题


I have the following namedQuery

select new test.entity.Emp(COALESCE(k.projectId,'N')
as projectId, k.projectName) from Emp o inner join o.projects k 

However I am getting error

expecting RIGHT_ROUND_BRACKET, found '('

How to handle COALESCE in namedQuery?

Are there any other ways to handle null values in JPA?


回答1:


Coalesce is supported by JPA 2.0 API.

The new construct is proprietary to Hibernate, not necessarily supported in all JPA implementations. First try the query without also trying to construct an object:

select COALESCE(k.projectId,'N') as projectId, k.projectName from Emp o inner join o.projects k



回答2:


I tried the following simple unit test, which passes successfully:

@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 class:

@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 class:

@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;
    }
}

Tested using EclipseLink 2.5.0:

    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.5.0</version>
    </dependency>



回答3:


Your brackets are messed up or you have a superfluous alias clause, which becomes easy to see when you indent your statement properly.

select 
    new test.entity.Emp(
        COALESCE(k.projectId,'N') as projectId, 
        k.projectName
    ) 
from Emp o inner join o.projects k 

try this instead:

select 
    new test.entity.Emp(
        COALESCE(k.projectId,'N'), 
        k.projectName
    ) 
from Emp o inner join o.projects k 


来源:https://stackoverflow.com/questions/27528976/coalesce-in-jpa-namedquery

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!