I use OpenJPA 2.1 on WebSphere Application Server 8. I have a bidirectional oneToMay relation like this:
@Entity(name = "table1")
public class Table1 {
@Id
@Column(columnDefinition = "DATE")
private Date date;
@OneToMany(mappedBy = "date", targetEntity = Table2.class, fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
private List<Table2> table2List;
}
@Entity(name = "table2")
public class Tabl2{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "fk_date", nullable = false)
private Table1 table1;
@Column(name = "value", nullable = false, columnDefinition = "INT")
private int value;
}
Now I want to select the whole table1 entity with a condition on table2 like this:
TypedQuery<WeekBean> q = em.createQuery(
"SELECT t1 from table1 t1 JOIN FETCH t1.table2List t2 WHERE t2.value = :value",
t1.class);
But this does not work, beacause I get an ArgumentException:
Exception in thread "main" <openjpa-2.1.1-SNAPSHOT-r422266:1141200 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: " Encountered "f" at character 50, but expected [",", ".", "GROUP", "HAVING", "INNER", "JOIN", "LEFT", "ORDER", "WHERE", <EOF>]."
at org.apache.openjpa.kernel.jpql.JPQLParser.parse(JPQLParser.java:51)
at org.apache.openjpa.kernel.ExpressionStoreQuery.newCompilation(ExpressionStoreQuery.java:154)
at org.apache.openjpa.datacache.QueryCacheStoreQuery.newCompilation(QueryCacheStoreQuery.java:262)
at org.apache.openjpa.kernel.QueryImpl.newCompilation(QueryImpl.java:672)
at org.apache.openjpa.kernel.QueryImpl.compilationFromCache(QueryImpl.java:654)
at org.apache.openjpa.kernel.QueryImpl.compileForCompilation(QueryImpl.java:620)
at org.apache.openjpa.kernel.QueryImpl.compileForExecutor(QueryImpl.java:682)
at org.apache.openjpa.kernel.QueryImpl.compile(QueryImpl.java:589)
at org.apache.openjpa.persistence.EntityManagerImpl.createQuery(EntityManagerImpl.java:996)
at com.ibm.ws.persistence.EntityManagerImpl.createQuery(EntityManagerImpl.java:107)
at com.ibm.ws.persistence.EntityManagerImpl.createQuery(EntityManagerImpl.java:86)
at com.ibm.ws.persistence.EntityManagerImpl.createQuery(EntityManagerImpl.java:34)
at org.apache.openjpa.persistence.EntityManagerImpl.createQuery(EntityManagerImpl.java:974)
How can I use a JOIN FETCH with a condition on the collection?
Best Regards Veote
According JPA 2.0 specification such a construct is not supported, and looks like OpenJPA also does not provide functionality as vendor extension:
The association referenced by the right side of the FETCH JOIN clause must be an association that belongs to an entity that is returned as a result of the query. It is not permitted to specify an identification variable for the entities referenced by the right side of the FETCH JOIN clause, and hence references to the implicitly fetched entities cannot appear elsewhere in the query.
In your case this means that you cannot define t2
and as a consequence you cannot use it in the WHERE clause.