2016-10-20 3 views
0

Мой Java код строит следующую JPQL (динамически) задан набор параметров, передаваемых в RESTful конечную точку:JPQL Множественные JOIN запрос той же таблицы

SELECT i FROM Item i JOIN FETCH i.itemCharacterizations ic2 WHERE 1 = 1 AND ic2.type = 2 AND ic2.intValue = 0 AND LOWER(i.externalId) LIKE :itemName 

Это приводит к следующей ошибке:

<openjpa-2.2.0-r422266:1244990 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: "Encountered "ic2" at character 57, but expected: [",", ".", "GROUP", "HAVING", "INNER", "JOIN", "LEFT", "ORDER", "WHERE", <EOF>]." while parsing JPQL "SELECT i FROM Item i JOIN FETCH i.itemCharacterizations ic2 WHERE 1 = 1 AND ic2.type = 2 AND ic2.intValue = 0 AND LOWER(i.externalId) LIKE :itemName". See nested stack trace for original parse error. 

Вот мой Java-код:

. 
    . 
    . 
    . 
    List<Item> items = null; 
    // Query base string - WHERE 1 = 1 used strictly for convenience purposes. 
    StringBuilder queryBuffer = new StringBuilder(); 
    if (itemGradeLevelId == -1 && itemContentAreaId == -1) { 
     queryBuffer.append("SELECT i FROM Item i WHERE 1 = 1"); 
    } 
    else { 
     queryBuffer.append("SELECT i FROM Item i"); 
     if (itemGradeLevelId > -1) { 
      queryBuffer.append(" JOIN FETCH i.itemCharacterizations ic1"); 
     } 
     if (itemContentAreaId > -1) { 
      queryBuffer.append(" JOIN FETCH i.itemCharacterizations ic2"); 
     } 
     queryBuffer.append(" WHERE 1 = 1"); 
     if (itemGradeLevelId > -1) { 
      queryBuffer.append(" AND ic1.type = " + ItemCharacterizationTypeConstants.GRADE_LEVEL + 
           " AND ic1.intValue = " + itemGradeLevelId); 
     } 
     if (itemContentAreaId > -1) { 
      queryBuffer.append(" AND ic2.type = " + ItemCharacterizationTypeConstants.CONTENT_AREA + 
           " AND ic2.intValue = " + itemContentAreaId); 
     } 
    } 
    . 
    . 
    . 
    . 
    TypedQuery<Item> itemQuery = this.entityManager.createQuery(queryBuffer.toString(), Item.class); 
    items = itemQuery.getResultList(); 
    return items; 
} 

Я не уверен, что правильный синтаксис будет для ш Шляпа Я пытаюсь выполнить (что):

Выберите товара Entity учитывая следующие отношения определены в моем Item Entity:

@OneToMany(fetch = FetchType.EAGER) 
@JoinColumn(name = "i_id") 
private List<ItemCharacterization> itemCharacterizations; 

И следующие поля ItemCharacterization Entity:

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name="id") 
private long id; 

@Basic 
@Column(name="i_id") 
private long itemId; 

@Basic 
@Column(name="ic_type") 
private int type; 

@Basic 
@Column(name="ic_value") 
private int intValue; 

@Basic 
@Column(name="ic_value_str") 
private String strValue; 
+2

Я бы предпочел изменить 'JOIN FETCH i.itemCharacterizations ic2'' 'JOIN ItemCharacterizations ic2' –

+0

@prajeeshkumar - Хороший материал. JOIN не работает, но INNER JOIN сделал. Благодаря! –

ответ

0

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

В запросе

SELECT i FROM Item i JOIN FETCH i.itemCharacterizations ic2 WHERE 1 = 1 AND ic2.type = 2 AND ic2.intValue = 0 AND LOWER(i.externalId) LIKE :itemName 

идентификации переменной (ic2) в ассоциации используется, который не разрешен в JPA specification section 4.4.5.3, который гласит:

The association referenced by the right side of the FETCH JOIN clause must be an association or element collection that is referenced from an entity or embeddable that is returned as a result of the query.

It is not permitted to specify an identification variable for the objects referenced by the right side of the FETCH JOIN clause, and hence references to the implicitly fetched entities or elements cannot appear elsewhere in the query.

В намерения запроса не до fetch join этих двух объектов, но вместо этого, чтобы их объединить вместе, ключевое слово FETCH необходимо удалить из запроса, как в:

SELECT i FROM Item i JOIN i.itemCharacterizations ic2 WHERE 1 = 1 AND ic2.type = 2 AND ic2.intValue = 0 AND LOWER(i.externalId) LIKE :itemName 

, который должен вернуть коллекцию Item с соответствующими объектами ItemCharacterization.

Смежные вопросы