This is an automated email from the ASF dual-hosted git repository.
solomax pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openjpa.git
The following commit(s) were added to refs/heads/master by this push:
new f2520c06d [OPENJPA-2925] Clearing result cache before loading eager
joins
f2520c06d is described below
commit f2520c06dd23b50f6b6a5d9a1e9e004176d2ae81
Author: Paulo Cristovão de Araújo Silva Filho <[email protected]>
AuthorDate: Wed Apr 23 04:25:52 2025 -0300
[OPENJPA-2925] Clearing result cache before loading eager joins
* [OPENJPA-2925] Tests for issue
* OPENJPA-2925 Clearing result cache before loading eager joins
---------
Co-authored-by: Maxim Solodovnik <[email protected]>
---
.../openjpa/jdbc/kernel/JDBCStoreManager.java | 5 +-
.../apache/openjpa/persistence/recursive/Cat.java | 75 +++++++++++++
.../openjpa/persistence/recursive/Human.java | 63 +++++++++++
.../TestRecursiveThenNonRecursiveRelationship.java | 81 ++++++++++++++
.../src/it/nonRecursiveRelations/pom.xml | 116 +++++++++++++++++++++
.../apache/openjpa/tools/maven/recursive/Cat.java | 77 ++++++++++++++
.../openjpa/tools/maven/recursive/Human.java | 65 ++++++++++++
.../src/main/resources/META-INF/persistence.xml | 37 +++++++
.../maven/test/NonRecursiveRelationsTest.java | 79 ++++++++++++++
9 files changed, 597 insertions(+), 1 deletion(-)
diff --git
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
index af0a689f9..b8b810771 100644
---
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
+++
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
@@ -1144,9 +1144,12 @@ public class JDBCStoreManager implements StoreManager,
JDBCStore {
if (eres == res) {
if (eagerToMany == null && fm.isEagerSelectToMany())
eagerToMany = fm;
- else
+ else {
+ res.setMappedByFieldMapping(null);
+ res.setMappedByValue(null);
fm.loadEagerJoin(sm, this,
fetch.traverseJDBC(fm), res);
+ }
}
else if (eres != null) {
processed = fm.loadEagerParallel(sm, this,
diff --git
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/recursive/Cat.java
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/recursive/Cat.java
new file mode 100644
index 000000000..6f43bccdf
--- /dev/null
+++
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/recursive/Cat.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.recursive;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToMany;
+
+@Entity
+public class Cat {
+ @Id
+ @GeneratedValue
+ private int id;
+
+ @OneToMany(mappedBy = "parent", fetch = FetchType.EAGER)
+ private List<Cat> children = new ArrayList<>();
+ @ManyToOne
+ private Cat parent;
+ @ManyToOne
+ private Human human;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public List<Cat> getChildren() {
+ return children;
+ }
+
+ public void setChildren(List<Cat> children) {
+ this.children = children;
+ }
+
+ public Cat getParent() {
+ return parent;
+ }
+
+ public void setParent(Cat parent) {
+ this.parent = parent;
+ }
+
+ public Human getHuman() {
+ return human;
+ }
+
+ public void setHuman(Human human) {
+ this.human = human;
+ }
+}
diff --git
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/recursive/Human.java
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/recursive/Human.java
new file mode 100644
index 000000000..a3d0bc415
--- /dev/null
+++
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/recursive/Human.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.recursive;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+import jakarta.persistence.OneToMany;
+
+@Entity
+public class Human {
+ @Id
+ @GeneratedValue
+ private int id;
+ private String name;
+
+ @OneToMany(mappedBy = "human", fetch = FetchType.EAGER)
+ private List<Cat> cats = new ArrayList<>();
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public List<Cat> getCats() {
+ return cats;
+ }
+
+ public void setCats(List<Cat> cats) {
+ this.cats = cats;
+ }
+}
diff --git
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/recursive/TestRecursiveThenNonRecursiveRelationship.java
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/recursive/TestRecursiveThenNonRecursiveRelationship.java
new file mode 100644
index 000000000..a801a510c
--- /dev/null
+++
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/recursive/TestRecursiveThenNonRecursiveRelationship.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.recursive;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+import jakarta.persistence.EntityManager;
+
+/**
+ * Test accessing a non-recursive relation of an instance that has been loaded
via a recursive relation.
+ */
+public class TestRecursiveThenNonRecursiveRelationship extends
SingleEMFTestCase {
+ @Override
+ public void setUp() {
+ setUp(DROP_TABLES, Cat.class, Human.class,
+ "openjpa.ConnectionFactoryProperties", "PrintParameters=True",
+ "openjpa.Log", "SQL=trace");
+ }
+
+ public void testRelationAccessedViaRecursiveRelationship() {
+ final String ALICE = "Alice";
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+
+ Human alice = new Human();
+ alice.setName(ALICE);
+ em.persist(alice);
+ Human bob = new Human();
+ bob.setName("Bob");
+ em.persist(bob);
+
+ Cat parent = new Cat();
+ parent.setHuman(alice);
+ em.persist(parent);
+
+ Cat kitten1 = new Cat();
+ kitten1.setParent(parent);
+ kitten1.setHuman(bob);
+ em.persist(kitten1);
+
+ // Add a sibling that belongs to the same human so that later, when we
are finding kitten1, parent will not be
+ // loaded directly, but instead via the path
`kitten1.human.cats.parent`. Needed to reproduce
+ Cat kitten2 = new Cat();
+ kitten2.setParent(parent);
+ kitten2.setHuman(bob);
+ em.persist(kitten2);
+
+ em.getTransaction().commit();
+
+ int catId = parent.getId();
+ int kitten1Id = kitten1.getId();
+
+ em.close();
+ em = emf.createEntityManager();
+
+ Cat jpqlKitten_1 = em.createQuery("SELECT c FROM Cat c WHERE c.id =
:id", Cat.class)
+ .setParameter("id", kitten1Id)
+ .getSingleResult();
+ Cat kitten_1 = em.find(Cat.class, kitten1Id);
+ assertEquals(ALICE, kitten_1.getParent().getHuman().getName());
+ assertEquals(ALICE, jpqlKitten_1.getParent().getHuman().getName());
+
+ em.close();
+ }
+}
diff --git
a/openjpa-tools/openjpa-maven-plugin/src/it/nonRecursiveRelations/pom.xml
b/openjpa-tools/openjpa-maven-plugin/src/it/nonRecursiveRelations/pom.xml
new file mode 100644
index 000000000..2b7e4b8d6
--- /dev/null
+++ b/openjpa-tools/openjpa-maven-plugin/src/it/nonRecursiveRelations/pom.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<!--
+ Maven release plugin requires the project tag to be on a single line.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+
+ <groupId>org.apache.openjpa.tools.openjpa-maven-plugin.testing</groupId>
+ <artifactId>modifyDatabase</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.13.2</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.openjpa</groupId>
+ <artifactId>openjpa-kernel</artifactId>
+ <version>@pom.version@</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openjpa</groupId>
+ <artifactId>openjpa-jdbc</artifactId>
+ <version>@pom.version@</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openjpa</groupId>
+ <artifactId>openjpa-persistence-jdbc</artifactId>
+ <version>@pom.version@</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <version>@hsqldb.version@</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-dbcp2</artifactId>
+ <version>@dbcp2.version@</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.5.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.openjpa</groupId>
+ <artifactId>openjpa-maven-plugin</artifactId>
+ <version>@pom.version@</version>
+ <configuration>
+
<includes>**/recursive/*.class</includes>
+
<addDefaultConstructor>true</addDefaultConstructor>
+
<enforcePropertyRestrictions>true</enforcePropertyRestrictions>
+
<persistenceXmlFile>${project.build.directory}/classes/META-INF/persistence.xml</persistenceXmlFile>
+ </configuration>
+ <executions>
+ <execution>
+ <id>enhancer</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>enhance</goal>
+ </goals>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <version>@hsqldb.version@</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-dbcp2</artifactId>
+ <version>@dbcp2.version@</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+
+ </plugins>
+ </build>
+
+</project>
diff --git
a/openjpa-tools/openjpa-maven-plugin/src/it/nonRecursiveRelations/src/main/java/org/apache/openjpa/tools/maven/recursive/Cat.java
b/openjpa-tools/openjpa-maven-plugin/src/it/nonRecursiveRelations/src/main/java/org/apache/openjpa/tools/maven/recursive/Cat.java
new file mode 100644
index 000000000..6ff2703e3
--- /dev/null
+++
b/openjpa-tools/openjpa-maven-plugin/src/it/nonRecursiveRelations/src/main/java/org/apache/openjpa/tools/maven/recursive/Cat.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.tools.maven.recursive;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "cat")
+public class Cat {
+ @Id
+ @GeneratedValue
+ private int id;
+
+ @OneToMany(mappedBy = "parent", fetch = FetchType.EAGER)
+ private List<Cat> children = new ArrayList<>();
+ @ManyToOne
+ private Cat parent;
+ @ManyToOne
+ private Human human;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public List<Cat> getChildren() {
+ return children;
+ }
+
+ public void setChildren(List<Cat> children) {
+ this.children = children;
+ }
+
+ public Cat getParent() {
+ return parent;
+ }
+
+ public void setParent(Cat parent) {
+ this.parent = parent;
+ }
+
+ public Human getHuman() {
+ return human;
+ }
+
+ public void setHuman(Human human) {
+ this.human = human;
+ }
+}
diff --git
a/openjpa-tools/openjpa-maven-plugin/src/it/nonRecursiveRelations/src/main/java/org/apache/openjpa/tools/maven/recursive/Human.java
b/openjpa-tools/openjpa-maven-plugin/src/it/nonRecursiveRelations/src/main/java/org/apache/openjpa/tools/maven/recursive/Human.java
new file mode 100644
index 000000000..c164a75de
--- /dev/null
+++
b/openjpa-tools/openjpa-maven-plugin/src/it/nonRecursiveRelations/src/main/java/org/apache/openjpa/tools/maven/recursive/Human.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.tools.maven.recursive;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "human")
+public class Human {
+ @Id
+ @GeneratedValue
+ private int id;
+ private String name;
+
+ @OneToMany(mappedBy = "human", fetch = FetchType.EAGER)
+ private List<Cat> cats = new ArrayList<>();
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public List<Cat> getCats() {
+ return cats;
+ }
+
+ public void setCats(List<Cat> cats) {
+ this.cats = cats;
+ }
+}
diff --git
a/openjpa-tools/openjpa-maven-plugin/src/it/nonRecursiveRelations/src/main/resources/META-INF/persistence.xml
b/openjpa-tools/openjpa-maven-plugin/src/it/nonRecursiveRelations/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 000000000..b26215bf6
--- /dev/null
+++
b/openjpa-tools/openjpa-maven-plugin/src/it/nonRecursiveRelations/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the
+ NOTICE file distributed with this work for additional information
regarding copyright ownership. The ASF
+ licenses this file to you under the Apache License, Version 2.0 (the
"License"); you may not use this file
+ except in compliance with the License. You may obtain a copy of the
License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ either express or implied. See the License for the specific language
governing permissions and limitations under
+ the License.
+ -->
+
+<persistence version="3.0" xmlns="https://jakarta.ee/xml/ns/persistence"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence
+ https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd">
+
+ <!-- simply all annotated persistent entities will be part of this unit-->
+ <persistence-unit name="TestUnit">
+
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+ <class>org.apache.openjpa.tools.maven.recursive.Cat</class>
+ <class>org.apache.openjpa.tools.maven.recursive.Human</class>
+
+ <properties>
+ <property name="openjpa.RuntimeUnenhancedClasses"
value="unsupported" />
+ <property name="openjpa.ConnectionDriverName"
value="org.hsqldb.jdbcDriver" />
+ <property name="openjpa.ConnectionURL"
value="jdbc:hsqldb:file:target/openjpa-hsqldb;hsqldb.lock_file=false" />
+ <property name="openjpa.ConnectionUserName" value="SA" />
+ <property name="openjpa.ConnectionPassword" value="" />
+ <property name="openjpa.jdbc.SynchronizeMappings"
value="buildSchema" />
+ <property name="openjpa.Log" value="DefaultLevel=TRACE,
Tool=TRACE, SQL=TRACE" />
+ </properties>
+ </persistence-unit>
+</persistence>
diff --git
a/openjpa-tools/openjpa-maven-plugin/src/it/nonRecursiveRelations/src/test/java/org/apache/openjpa/tools/maven/test/NonRecursiveRelationsTest.java
b/openjpa-tools/openjpa-maven-plugin/src/it/nonRecursiveRelations/src/test/java/org/apache/openjpa/tools/maven/test/NonRecursiveRelationsTest.java
new file mode 100644
index 000000000..795963421
--- /dev/null
+++
b/openjpa-tools/openjpa-maven-plugin/src/it/nonRecursiveRelations/src/test/java/org/apache/openjpa/tools/maven/test/NonRecursiveRelationsTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.tools.maven.test;
+
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.EntityManagerFactory;
+import jakarta.persistence.Persistence;
+import org.apache.openjpa.tools.maven.recursive.Cat;
+import org.apache.openjpa.tools.maven.recursive.Human;
+
+public class NonRecursiveRelationsTest {
+ @Test
+ public void testRelationAccessedViaRecursiveRelationship() {
+ final String ALICE = "Alice";
+ EntityManagerFactory emf =
Persistence.createEntityManagerFactory("TestUnit");
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+
+ Human alice = new Human();
+ alice.setName(ALICE);
+ em.persist(alice);
+ Human bob = new Human();
+ bob.setName("Bob");
+ em.persist(bob);
+
+ Cat parent = new Cat();
+ parent.setHuman(alice);
+ em.persist(parent);
+
+ Cat kitten1 = new Cat();
+ kitten1.setParent(parent);
+ kitten1.setHuman(bob);
+ em.persist(kitten1);
+
+ // Add a sibling that belongs to the same human so that later, when we
are finding kitten1, parent will not be
+ // loaded directly, but instead via the path
`kitten1.human.cats.parent`. Needed to reproduce
+ Cat kitten2 = new Cat();
+ kitten2.setParent(parent);
+ kitten2.setHuman(bob);
+ em.persist(kitten2);
+
+ em.getTransaction().commit();
+
+ int catId = parent.getId();
+ int kitten1Id = kitten1.getId();
+
+ em.close();
+ em = emf.createEntityManager();
+
+ Cat jpqlKitten_1 = em.createQuery("SELECT c FROM Cat c WHERE c.id =
:id", Cat.class)
+ .setParameter("id", kitten1Id)
+ .getSingleResult();
+ Cat kitten_1 = em.find(Cat.class, kitten1Id);
+ assertEquals(ALICE, kitten_1.getParent().getHuman().getName());
+ assertEquals(ALICE, jpqlKitten_1.getParent().getHuman().getName());
+
+ em.close();
+ }
+}