简体   繁体   中英

JPQL Multiple JOIN query to same table

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM