[
https://issues.apache.org/jira/browse/OPENJPA-2931?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18142816#comment-18142816
]
ASF subversion and git services commented on OPENJPA-2931:
----------------------------------------------------------
Commit 79fe85b4c23cf6a7fd54088d528cffede784c423 in openjpa's branch
refs/heads/OPENJPA-3074 from Richard Zowalla
[ https://gitbox.apache.org/repos/asf?p=openjpa.git;h=79fe85b4c ]
[OPENJPA-2931] Comparing objects with composite keys through criteria API
doesn't work in joins (#295)
* [OPENJPA-2931] Give criteria paths the metadata of the type they navigate to
Comparing an entity with a composite primary key on a path navigated from a
join, such as cb.equal(join.get(Topic_.subject), subject), failed with a
NullPointerException in EqualExpression. Since OPENJPA-2631 the store reads
the metadata of the compared path to decide whether to compare all primary
key columns, but PathImpl only set metadata on root paths: a path starting at
a registered join variable or a correlated join carried none, and a path
navigated from a root kept the metadata of the root instead of the type of
the field.
PathImpl now sets the metadata the way the JPQL parser does: a path starting
at a variable carries the metadata of the variable, and traversing a field
sets the metadata of the field's embedded or declared type, keeping the
previous metadata for basic and multi-valued fields.
* [OPENJPA-2931] Compare all PK columns of derived identities and set metadata
on plural joins
Now that criteria paths carry the metadata of the type they navigate to,
EqualExpression checked whether the first primary key field of that type
is embedded. For an entity with a derived identity, whose first primary
key field is a relation, only the first column was compared and queries
returned too many rows. EqualExpression now compares all columns of an
embedded value, of an entity whose primary key is embedded or basic, and
of an entity whose primary key columns are exactly the compared columns,
and no longer fails when the value carries no metadata.
Plural joins and the key of a map join built their kernel paths without
metadata as well, so comparing them with an entity with a composite
primary key still failed with a NullPointerException. They now carry the
metadata of the element and of the key.
* [OPENJPA-2931] Add the issue to the release notes
---------
Co-authored-by: Paulo Cristovão de Araújo Silva Filho <[email protected]>
Co-authored-by: Maxim Solodovnik <[email protected]>
> Comparing objects with composite keys through criteria API doesn't work in
> joins
> --------------------------------------------------------------------------------
>
> Key: OPENJPA-2931
> URL: https://issues.apache.org/jira/browse/OPENJPA-2931
> Project: OpenJPA
> Issue Type: Bug
> Components: criteria, query, sql
> Affects Versions: 3.1.2
> Reporter: Pawel Veselov
> Assignee: Richard Zowalla
> Priority: Major
> Fix For: 4.2.0
>
>
> I'm relatively certain this affects downstream as well.
> This is probably incomplete/incorrect fix for OPENJPA-2631.
> I've added this test to TestCompositePrimaryKeys.java:
> {code:java}
> public void testFindUsingCriteriaBuilderOnSubjectWithJoin() {
> Subject sub = em.find(Subject.class, new SubjectKey(1, "Type"));
> CriteriaBuilder builder = em.getCriteriaBuilder();
> CriteriaQuery<SubTopic> cq = builder.createQuery(SubTopic.class);
> Root<SubTopic> root = cq.from(SubTopic.class);
> Join<SubTopic, Topic> join = root.join(SubTopic_.topic);
> cq.where(builder.equal(join.get(Topic_.subject), sub));
> root.fetch(SubTopic_.topic);
> TypedQuery<SubTopic> query = em.createQuery(cq);
> SubTopic found = query.getSingleResult();
> Assert.assertNotNull(found);
> Assert.assertEquals(Integer.valueOf(8), found.getId());
> }
> {code}
> Having a basic additional entity SubTopic:
> {code:java}
> @Entity
> @Table(name = "SUB_TOPIC")
> public class SubTopic {
> @Id
> @Column(name = "ID")
> private Integer id;
> @ManyToOne(fetch = FetchType.LAZY)
> private Topic topic;
> public SubTopic() {
> }
> }
> {code}
> The test fails with:
> {noformat}
> Caused by: java.lang.NullPointerException
> at
> org.apache.openjpa.jdbc.kernel.exps.EqualExpression.appendTo(EqualExpression.java:89)
> at
> org.apache.openjpa.jdbc.kernel.exps.CompareEqualExpression.appendTo(CompareEqualExpression.java:113)
> at
> org.apache.openjpa.jdbc.kernel.exps.BindVariableAndExpression.appendTo(BindVariableAndExpression.java:61)
> at
> org.apache.openjpa.jdbc.kernel.exps.SelectConstructor.buildWhere(SelectConstructor.java:313)
> at
> org.apache.openjpa.jdbc.kernel.exps.SelectConstructor.evaluate(SelectConstructor.java:95)
> at
> org.apache.openjpa.jdbc.kernel.JDBCStoreQuery.createWhereSelects(JDBCStoreQuery.java:372)
> at
> org.apache.openjpa.jdbc.kernel.JDBCStoreQuery.executeQuery(JDBCStoreQuery.java:203)
> at
> org.apache.openjpa.kernel.ExpressionStoreQuery$DataStoreExecutor.executeQuery(ExpressionStoreQuery.java:831)
> at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:1060)
> {noformat}
> OPENJPA-2631 relies on the ClassMetadata being there for the evaluated paths,
> but in case of joins, it's not set.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)