My Java code is constructing the following JPQL (dynamically) given a set of parameters passed into a RESTful endpoint:
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
This is resulting in the following error:
<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.
Here is my Java code:
.
.
.
.
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;
}
I'm not certain what the correct syntax would be for what I am trying to accomplish (which is):
Select an Item Entity given the following relationship defined in my Item Entity:
@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "i_id")
private List<ItemCharacterization> itemCharacterizations;
And the following ItemCharacterization Entity fields:
@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;
The question seems to have been answered. But just to give the reason why it was causing the problem.
In the query
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
identification variable ( ic2
) to the association is used, which is not allowed in the JPA specification section 4.4.5.3 which states:
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 .
As the intention of the query is not to fetch join
the two entities but rather to join them together, the FETCH
keyword must be removed from the query as in:
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
which should return a collection of Item
s with their associated ItemCharacterization
instances.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.