2014-12-17 4 views
3

У меня есть следующие namedQueryCOALESCE в JPA 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, нашел '('

Как обрабатывать COALESCE в namedQuery?

Есть ли другие способы обработки nul l в JPA?

ответ

3

Coalesce is supported by JPA 2.0 API.

Конструкция new является собственностью Hibernate, не обязательно поддерживаемой во всех реализациях JPA. Сначала попробуйте запрос без также пытается построить объект:

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

Он жалуется на 'колонке 41: ошибка синтаксиса в [(] внутреннего Exception:. Линия 1:41: ожидая "от", нашел '('' – user75ponic

1

Я попробовал следующий простой модульный тест, который проходит успешно:

@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> 
+0

Да, он работает без проблем с помощью Eclipselink, однако с помощью Toplink он не работает. – user75ponic

+0

Какая версия TopLink вы используете в своем приложении? Библиотеки EclipseLink включены в TopLink, поэтому вам может потребоваться обновить библиотеки EclipseLink до последней версии. Если вы используете сервер Weblogic, вы можете обратиться к этому руководству: http://docs.oracle.com/cd/E23943_01/doc.1111/e2 5034/tlandwls.htm # TLADG118 (просто используйте версию сервера, применимую к вашему делу) для обновления EclipseLink до последней версии. –

1

Ваших скобки перепутались или у вас есть лишний пункт псевдонима, который становится легко видеть, когда вы отступ вашего заявления правильно.

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 
Смежные вопросы