2016-06-30 9 views
0

Использование:Выбор вложенных Hibernate неизменные объекты бросками org.hibernate.hql.internal.ast.QuerySyntaxException: неожиданный маркер: новый

  • Hibernate 4.1.6
  • Spring 4,1
  • Java 8

у меня есть два неизменные модели данных:

Родитель модель

@Entity 
@Immutable 
@Table(name="PARENT_TABLE") 
public class Parent { 
    @Column(name="NAME") 
    private final String name; 

    @OneToMany(cascade=CascadeType.ALL, mappedBy="parent") 
    @MapKey(name="key") 
    Map<String, Child> children = new HashMap<>(1); 

    public Parent(String name) { 
     this.name = name; 
    } 

    public putChild(Child c) { 
     Child childWithRef = new Child(this, c.getKey()); 
     children.put(c.getKey(), childWithRef); 
    } 
} 

Ребенок модель

@Entity 
@Immutable 
@Table(name="CHILD_TABLE") 
public class Child { 
    @ManyToOne 
    @JoinColumn(name="PARENT_ID") //say Parent has a generated ID 
    private final Parent parent; 

    @Column(name="KEY") 
    private final String key; 

    public Child(Parent p, String key) { 
     this.parent = p; 
     this.key = key; 
    } 
} 

И я хочу, чтобы извлечь все дети, с их родителями, поэтому я стараюсь работает (entityManager от Spring):

entityManager.createQuery("SELECT new Child(new Parent('sample name'), c.key) FROM Child c").getResultList() 

Но я получаю исключение (проблема указана с второйnew):

org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: new near line 1, column ... 

Кто-нибудь знает, как извлечь вложенные неизменные объекты?

Я знаю, что Hibernate действительно против неизменности. Поскольку я выполняю только простые задачи с базой данных, я бы хотел, тем не менее, попробовать.

+0

необходимо указать, какие столбцы вам нужно, если вам нужны все вы положили «SELECT * FROM ребенка» – niceman

+0

Sure [есть] (http://docs.jboss.org/hibernate/core/3.5/reference/ en/html/queryhql.html # queryhql-select) ... – Eeko

+0

Прошу прощения, что я ошибся, nyway [this] (http://learningviacode.blogspot.com/2012/10/hql-and-new-keyword.html) предполагает, что вам нужно поставить полное имя – niceman

ответ

0

Ваш запрос является незаконным для JPQL. JPQL BNF (JPA 2.1 спецификации) говорится очень четко

select_expression ::= single_valued_path_expression | scalar_expression | aggregate_expression | 
    identification_variable | OBJECT(identification_variable) | constructor_expression 
constructor_expression ::= NEW constructor_name (constructor_item {, constructor_item}*) 
constructor_item ::= single_valued_path_expression | scalar_expression | aggregate_expression | 
    identification_variable 

Вы не можете гнездовых выражений конструктора.

Извлеките его в один объект, а затем разделите его на свою структуру. Например,

SELECT c.key FROM Child c 

Чтобы получить «ключ» от ребенка, а затем создайте объекты самостоятельно в своем коде.

EDIT ДЛЯ ПОЛНОГО КОД:

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

//fetch all fields without instantiating any models from Hibernate; 
//all aliases are for understanding only; 
//notice `INNER JOIN c.parent` for fetching the parent data 
List<Object[]> results = entityManager.createQuery("SELECT p.id as parentId, p.name as parentName, p.key as parentKey, c.key as childKey FROM Child c INNER JOIN c.parent").getResultList() 

//use map for parents identification 
Map<Long, Parent> parentsMap = new HashMap<>(results.size()) 

//now use the data to instantiate the immutable models 
results.forEach(resultRecord -> { 
    Long parentId = (Long) resultRecord[0]; 
    if (parentsMap.get(parentId) == null) { //first time meeting this parent 
     Parent p = new Parent(resultRecord[0], resultRecord[1], resultRecord[2]); 
     parentsMap.put(parentId, p); 
    } 

    Child c = new Child(parentsMap.get(parentId), resultRecord[3]); 
    parentsMap.get(parentId).putChild(c); 
} 
+0

OK, но ** Я надеюсь получить вложенные объекты **, чтобы не запускать предлагаемый запрос успешно ... Любое предложение получить их приветствуется :) – Eeko

+0

хорошо, это был бы более полный ответ, если бы вы сказали OP, что делать – niceman

+0

@niceman Я принял эту часть как прочитано; просто выберите все, что вам нужно, и сформируйте объекты в своем собственном коде (на это не накладные расходы). Теперь добавлено. –