solomax commented on code in PR #205: URL: https://github.com/apache/openjpa/pull/205#discussion_r4220400162
########## openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestTransientRefNoCascade.java: ########## @@ -0,0 +1,248 @@ +/* + * 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.simple; + +import jakarta.persistence.EntityManager; + +import org.apache.openjpa.persistence.InvalidStateException; +import org.apache.openjpa.persistence.test.SQLListenerTestCase; + +/** + * A relation with no cascade that points at a transient instance must be + * reported at flush time, while a relation that points at a detached + * instance stays tolerated (see OPENJPA-2940). Transient instances without + * an assigned identity must not cause a datastore lookup, because an + * instance without identity can never have been persisted. + */ +public class TestTransientRefNoCascade extends SQLListenerTestCase { + + @Override + public void setUp() { + setUp(UnenhancedNCDepartment.class, + UnenhancedNCAssignedDepartment.class, + UnenhancedNCEmployee.class, + CLEAR_TABLES, + "openjpa.RuntimeUnenhancedClasses", "supported"); + } + + /** + * An instance without an assigned identity was never persisted, so the + * flush must fail and must not probe the datastore for it. + */ + public void testTransientWithoutIdentityIsRejectedWithoutLookup() { + EntityManager em = emf.createEntityManager(); + try { + em.getTransaction().begin(); + UnenhancedNCEmployee emp = new UnenhancedNCEmployee(1L, "Smith"); + emp.setDepartment(new UnenhancedNCDepartment(null, "Ghost")); + em.persist(emp); + sql.clear(); + try { + em.flush(); + fail("Flush must not accept a transient reference on a " + + "relation without cascade"); + } catch (InvalidStateException ise) { + assertNotNull(ise.getFailedObject()); + } + assertEquals("No datastore lookup must be done for an instance " + + "without an assigned identity: " + sql, + 0, countSelects("TRNSREF_DEPT")); + } finally { + if (em.getTransaction().isActive()) + em.getTransaction().rollback(); + em.close(); + } + } + + /** + * An instance with an identity that has no store record was never + * persisted either, so the flush must still fail after the lookup. + */ + public void testTransientWithIdentityIsRejected() { + EntityManager em = emf.createEntityManager(); + try { + em.getTransaction().begin(); + UnenhancedNCEmployee emp = new UnenhancedNCEmployee(2L, "Jones"); + emp.setDepartment(new UnenhancedNCDepartment(4711L, "Ghost")); + em.persist(emp); + sql.clear(); + try { + em.flush(); + fail("Flush must not accept a transient reference on a " + + "relation without cascade"); + } catch (InvalidStateException ise) { + assertNotNull(ise.getFailedObject()); + } + assertEquals("The identity must be looked up exactly once: " + sql, + 1, countSelects("TRNSREF_DEPT")); + } finally { + if (em.getTransaction().isActive()) + em.getTransaction().rollback(); + em.close(); + } + assertNull("The employee must not have been written", + find(UnenhancedNCEmployee.class, 2L)); + } + + /** + * An instance of an entity with an application assigned identity that + * holds no identity at all must be rejected without a lookup, even if a + * store record exists for the default value of the identity type. + */ + public void testTransientWithoutAssignedIdentityIsRejectedWithoutLookup() { + EntityManager em = emf.createEntityManager(); + try { Review Comment: I would change these as `try-with-resources` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
