| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| // 01/05/2010-2.1 Guy Pelletier |
| // - 211324: Add additional event(s) support to the EclipseLink-ORM.XML Schema |
| // 01/26/2011-2.3 Guy Pelletier |
| // - 307664: Lifecycle callbacks not called for object from IndirectSet |
| // 07/15/2011-2.2.1 Guy Pelletier |
| // - 349424: persists during an preCalculateUnitOfWorkChangeSet event are lost |
| package org.eclipse.persistence.testing.tests.jpa.inheritance; |
| |
| import java.util.List; |
| import jakarta.persistence.EntityManager; |
| |
| import junit.framework.*; |
| import org.eclipse.persistence.testing.framework.junit.JUnitTestCase; |
| import org.eclipse.persistence.testing.models.jpa.inheritance.AAA; |
| import org.eclipse.persistence.testing.models.jpa.inheritance.Car; |
| import org.eclipse.persistence.testing.models.jpa.inheritance.Bus; |
| import org.eclipse.persistence.testing.models.jpa.inheritance.DDD; |
| import org.eclipse.persistence.testing.models.jpa.inheritance.MacBook; |
| import org.eclipse.persistence.testing.models.jpa.inheritance.SportsCar; |
| import org.eclipse.persistence.testing.models.jpa.inheritance.AbstractBus; |
| import org.eclipse.persistence.testing.models.jpa.inheritance.InheritanceTableCreator; |
| import org.eclipse.persistence.testing.models.jpa.inheritance.listeners.BusListener; |
| import org.eclipse.persistence.testing.models.jpa.inheritance.listeners.BusNativeListener; |
| import org.eclipse.persistence.testing.models.jpa.inheritance.listeners.VehicleListener; |
| import org.eclipse.persistence.testing.models.jpa.inheritance.listeners.ListenerSuperclass; |
| import org.eclipse.persistence.testing.models.jpa.inheritance.listeners.FueledVehicleListener; |
| import org.eclipse.persistence.testing.models.jpa.xml.inheritance.listeners.DefaultListener; |
| |
| public class LifecycleCallbackJunitTest extends JUnitTestCase { |
| private static Number m_busID; |
| |
| public LifecycleCallbackJunitTest() { |
| super(); |
| } |
| |
| public LifecycleCallbackJunitTest(String name) { |
| super(name); |
| } |
| |
| public static Test suite() { |
| TestSuite suite = new TestSuite(); |
| suite.setName("LifecycleCallbackJunitTest"); |
| suite.addTest(new LifecycleCallbackJunitTest("testSetup")); |
| suite.addTest(new LifecycleCallbackJunitTest("testPrePersistBusOverrideAndAbstractInheritAndDefault")); |
| suite.addTest(new LifecycleCallbackJunitTest("testPostPersistBusInheritAndDefault")); |
| suite.addTest(new LifecycleCallbackJunitTest("testPostLoadBusInheritAndDefault")); |
| suite.addTest(new LifecycleCallbackJunitTest("testPrePersistSportsCarInheritAndExcludeDefault")); |
| suite.addTest(new LifecycleCallbackJunitTest("testPostPersistSportsCarInheritAndExcludeDefault")); |
| suite.addTest(new LifecycleCallbackJunitTest("testPrePersistSportsCarOverride")); |
| suite.addTest(new LifecycleCallbackJunitTest("testQueryInNativePreUpdateEvent")); |
| suite.addTest(new LifecycleCallbackJunitTest("testDefaultListenerOnMacBook")); |
| suite.addTest(new LifecycleCallbackJunitTest("testPostLoadFromMembersOfSet")); |
| suite.addTest(new LifecycleCallbackJunitTest("testSessionEventListenerOnBus")); |
| |
| return suite; |
| } |
| |
| /** |
| * The setup is done as a test, both to record its failure, and to allow execution in the server. |
| */ |
| public void testSetup() { |
| new InheritanceTableCreator().replaceTables(JUnitTestCase.getServerSession()); |
| clearCache(); |
| } |
| |
| /** |
| * Test added for bug 307664. |
| */ |
| public void testPostLoadFromMembersOfSet() { |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| String aaaId; |
| |
| try { |
| int dddPostLoadCountInitial = 0; |
| int dddListenerPostLoadCountInitial = 0; |
| |
| AAA aaa = new AAA(); |
| DDD ddd = new DDD(); |
| ddd.setAaa(aaa); |
| aaa.getDdds().add(ddd); |
| |
| em.persist(aaa); |
| aaaId = aaa.getId(); |
| em.flush(); |
| |
| // This should fire a postLoad event ... |
| em.refresh(aaa); |
| DDD refreshedDDD = aaa.getDdds().iterator().next(); |
| |
| int dddPostLoadCountRefresh = refreshedDDD.getCount(); |
| int dddListenerPostLoadCountRefresh = refreshedDDD.getCount2(); |
| assertTrue("The PostLoad callback method on DDD was not called after the refresh.", (dddPostLoadCountRefresh - dddPostLoadCountInitial) == 1); |
| assertTrue("The PostLoad callback method on the DDD Listener was not called after the refresh.", (dddListenerPostLoadCountRefresh - dddListenerPostLoadCountInitial) == 1); |
| |
| commitTransaction(em); |
| |
| // Clear the cache and all the works. |
| clearCache(); |
| em.clear(); |
| |
| AAA findAAA = em.find(AAA.class, aaa.getId()); |
| // This should fire a postLoad event ... |
| DDD findDDD = findAAA.getDdds().iterator().next(); |
| int dddPostLoadCountFind = findDDD.getCount(); |
| int dddListenerPostLoadCountFind = findDDD.getCount2(); |
| assertTrue("The PostLoad callback method on DDD was not called afer the find.", (dddPostLoadCountFind - dddPostLoadCountRefresh) == 1); |
| assertTrue("The PostLoad callback method on the DDD Listener was not called afer the find.", (dddListenerPostLoadCountFind - dddListenerPostLoadCountRefresh) == 1); |
| |
| } catch (RuntimeException ex) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| throw ex; |
| } |
| } |
| |
| public void testPostLoadBusInheritAndDefault() { |
| int vehiclePostLoadCountBefore = VehicleListener.POST_LOAD_COUNT; |
| int defaultListenerPostLoadCountBefore = DefaultListener.POST_LOAD_COUNT; |
| |
| Bus bus = createEntityManager().find(Bus.class, m_busID); |
| |
| int vehiclePostLoadCountAfter = VehicleListener.POST_LOAD_COUNT; |
| int defaultListenerPostLoadCountAfter = DefaultListener.POST_LOAD_COUNT; |
| |
| assertFalse("The PostLoad callback method for Vehicle was not called.", vehiclePostLoadCountBefore == vehiclePostLoadCountAfter); |
| assertFalse("The PostLoad callback method for DefaultListener was not called.", defaultListenerPostLoadCountBefore == defaultListenerPostLoadCountAfter); |
| } |
| |
| public void testPostPersistBusInheritAndDefault() { |
| int busListenerPostPersistCountBefore = BusListener.POST_PERSIST_COUNT; |
| int fueledVehiclePostPersistCountBefore = FueledVehicleListener.POST_PERSIST_COUNT; |
| int defaultListenerPostPersistCountBefore = DefaultListener.POST_PERSIST_COUNT; |
| int defaultListenerPostLoadCountBefore = DefaultListener.POST_LOAD_COUNT; |
| int defaultListenerPostLoadCountIntermidiate; |
| |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| Bus bus = new Bus(); |
| bus.setPassengerCapacity(50); |
| bus.setFuelCapacity(175); |
| bus.setDescription("OC Transpo Bus"); |
| bus.setFuelType("Diesel"); |
| em.persist(bus); |
| em.flush(); |
| |
| // This should fire a postLoad event ... |
| em.refresh(bus); |
| defaultListenerPostLoadCountIntermidiate = DefaultListener.POST_LOAD_COUNT; |
| |
| jakarta.persistence.Query q = em.createQuery("select distinct b from Bus b where b.id = " + bus.getId()); |
| // This should not fire a postLoad event ... |
| q.getResultList(); |
| |
| commitTransaction(em); |
| } catch (RuntimeException ex) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| throw ex; |
| } |
| |
| int busListenerPostPersistCountAfter = BusListener.POST_PERSIST_COUNT; |
| int fueledVehiclePostPersistCountAfter = FueledVehicleListener.POST_PERSIST_COUNT; |
| int defaultListenerPostPersistCountAfter = DefaultListener.POST_PERSIST_COUNT; |
| int defaultListenerPostLoadCountAfter = DefaultListener.POST_LOAD_COUNT; |
| |
| assertFalse("The PostPersist callback method on BusListener was not called.", busListenerPostPersistCountBefore == busListenerPostPersistCountAfter); |
| assertFalse("The PostPersist callback method on FueledVehicleListener was not called.", fueledVehiclePostPersistCountBefore == fueledVehiclePostPersistCountAfter); |
| assertFalse("The PostPersist callback method on DefaultListener was not called.", defaultListenerPostPersistCountBefore == defaultListenerPostPersistCountAfter); |
| assertTrue("The PostLoad callback method on DefaultListener was called more than once, possibly on the refresh.", (defaultListenerPostLoadCountIntermidiate - defaultListenerPostLoadCountBefore) == 1); |
| assertTrue("The PostLoad callback method on DefaultListener was called on the getQueryResult().", defaultListenerPostLoadCountIntermidiate == defaultListenerPostLoadCountAfter); |
| } |
| |
| public void testPostPersistSportsCarInheritAndExcludeDefault() { |
| int fueledVehiclePostPersistCountBefore = FueledVehicleListener.POST_PERSIST_COUNT; |
| int defaultListenerPostPersistCountBefore = DefaultListener.POST_PERSIST_COUNT; |
| |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| SportsCar sportsCar = new SportsCar(); |
| sportsCar.setPassengerCapacity(4); |
| sportsCar.setFuelCapacity(55); |
| sportsCar.setDescription("Porshe"); |
| sportsCar.setFuelType("Gas"); |
| em.persist(sportsCar); |
| commitTransaction(em); |
| } catch (RuntimeException ex) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| throw ex; |
| } |
| |
| int fueledVehiclePostPersistCountAfter = FueledVehicleListener.POST_PERSIST_COUNT; |
| int defaultListenerPostPersistCountAfter = DefaultListener.POST_PERSIST_COUNT; |
| |
| assertFalse("The PostPersist callback method on FueledVehicleListener was not called.", fueledVehiclePostPersistCountBefore == fueledVehiclePostPersistCountAfter); |
| assertTrue("The PostPersist callback method on DefaultListener was called.", defaultListenerPostPersistCountBefore == defaultListenerPostPersistCountAfter); |
| } |
| |
| public void testPrePersistBusOverrideAndAbstractInheritAndDefault() { |
| int busListenerPrePersistCountBefore = BusListener.PRE_PERSIST_COUNT; |
| int busNativeListenerPreWriteCountBefore = BusNativeListener.PRE_WRITE_COUNT; |
| int busNativeListenerPostWriteCountBefore = BusNativeListener.POST_WRITE_COUNT; |
| int listenerSuperclassPrePersistCountBefore = ListenerSuperclass.COMMON_PRE_PERSIST_COUNT; |
| int abstractBusPrePeristCountBefore = AbstractBus.PRE_PERSIST_COUNT; |
| int defaultListenerPrePersistCountBefore = DefaultListener.PRE_PERSIST_COUNT; |
| |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| Bus bus = new Bus(); |
| bus.setPassengerCapacity(30); |
| bus.setFuelCapacity(100); |
| bus.setDescription("School Bus"); |
| bus.setFuelType("Diesel"); |
| em.persist(bus); |
| m_busID = bus.getId(); |
| commitTransaction(em); |
| } catch (RuntimeException ex) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| throw ex; |
| } |
| |
| closeEntityManager(em); |
| |
| int busListenerPrePersistCountAfter = BusListener.PRE_PERSIST_COUNT; |
| int busNativeListenerPreWriteCountAfter = BusNativeListener.PRE_WRITE_COUNT; |
| int busNativeListenerPostWriteCountAfter = BusNativeListener.POST_WRITE_COUNT; |
| int listenerSuperclassPrePersistCountAfter = ListenerSuperclass.COMMON_PRE_PERSIST_COUNT; |
| int abstractBusPrePeristCountAfter = AbstractBus.PRE_PERSIST_COUNT; |
| int defaultListenerPrePersistCountAfter = DefaultListener.PRE_PERSIST_COUNT; |
| |
| assertFalse("The PrePersist callback method on BusListener was not called.", busListenerPrePersistCountBefore == busListenerPrePersistCountAfter); |
| assertFalse("The PreWrite (native) callback method on BusNativeListener was not called.", busNativeListenerPreWriteCountBefore == busNativeListenerPreWriteCountAfter); |
| assertFalse("The PostWrite (native) callback method on BusNativeListener was not called.", busNativeListenerPostWriteCountBefore == busNativeListenerPostWriteCountAfter); |
| assertTrue("The PrePersist callback method on ListenerSuperclass was called.", listenerSuperclassPrePersistCountBefore == listenerSuperclassPrePersistCountAfter); |
| assertFalse("The PrePersist callback method on AbstractBus was not called.", abstractBusPrePeristCountBefore == abstractBusPrePeristCountAfter); |
| assertFalse("The PrePersist callback method on DefaultListener was not called.", defaultListenerPrePersistCountBefore == defaultListenerPrePersistCountAfter); |
| assertFalse("The PrePersist callback method on DefaultListener was called more than once.", defaultListenerPrePersistCountAfter - defaultListenerPrePersistCountBefore >1 ); |
| } |
| |
| public void testPrePersistSportsCarInheritAndExcludeDefault() { |
| int listenerSuperclassPrePersistCountBefore = ListenerSuperclass.COMMON_PRE_PERSIST_COUNT; |
| int defaultListenerPrePersistCountBefore = DefaultListener.PRE_PERSIST_COUNT; |
| |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| SportsCar sportsCar = new SportsCar(); |
| sportsCar.setPassengerCapacity(2); |
| sportsCar.setFuelCapacity(60); |
| sportsCar.setDescription("Corvette"); |
| sportsCar.setFuelType("Gas"); |
| em.persist(sportsCar); |
| commitTransaction(em); |
| } catch (RuntimeException ex) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| throw ex; |
| } |
| |
| closeEntityManager(em); |
| |
| int listenerSuperclassPrePersistCountAfter = ListenerSuperclass.COMMON_PRE_PERSIST_COUNT; |
| int defaultListenerPrePersistCountAfter = DefaultListener.PRE_PERSIST_COUNT; |
| |
| assertFalse("The PrePersist callback method on ListenerSuperclass was not called.", listenerSuperclassPrePersistCountBefore == listenerSuperclassPrePersistCountAfter); |
| assertTrue("The PrePersist callback method on DefaultListener was called.", defaultListenerPrePersistCountBefore == defaultListenerPrePersistCountAfter); |
| } |
| |
| public void testPrePersistSportsCarOverride() { |
| int carPrePersistCountBefore = Car.PRE_PERSIST_COUNT; |
| int sportsCarPrePersistCountBefore = SportsCar.PRE_PERSIST_COUNT; |
| |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| SportsCar sportsCar = new SportsCar(); |
| sportsCar.setPassengerCapacity(2); |
| sportsCar.setFuelCapacity(90); |
| sportsCar.setDescription("Viper"); |
| sportsCar.setFuelType("Gas"); |
| em.persist(sportsCar); |
| commitTransaction(em); |
| } catch (RuntimeException ex) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| throw ex; |
| } |
| |
| closeEntityManager(em); |
| |
| int carPrePersistCountAfter = Car.PRE_PERSIST_COUNT; |
| int sportsCarPrePersistCountAfter = SportsCar.PRE_PERSIST_COUNT; |
| |
| assertTrue("The PrePersist callback method on Car was called.", carPrePersistCountBefore == carPrePersistCountAfter); |
| assertFalse("The PrePersist callback method on Sports car was not called.", sportsCarPrePersistCountBefore == sportsCarPrePersistCountAfter); |
| } |
| |
| /** |
| * bug: 243993 - RepeatableWriteUnitOfWork's usage of UnitOfWorkImpl can cause ConcurrentModificationException |
| * - will occur if a native EclipseLink preUpdate event reads entities into the UOW, as it occurs while |
| * the uow is iterating over its clone list. |
| */ |
| public void testQueryInNativePreUpdateEvent(){ |
| clearCache(); |
| |
| EntityManager em = createEntityManager(); |
| List<Bus> results = em.createQuery("Select e from Bus e").getResultList(); |
| for (Bus bus:results){ |
| bus.setDescription("QueryInNativePreUpdateEvent"); |
| } |
| beginTransaction(em); |
| try{ |
| em.flush(); |
| } finally { |
| if(this.isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| } |
| } |
| |
| public void testDefaultListenerOnMacBook() { |
| // Tests the default listeners on those entities that don't have their |
| // own separate entity listener(s) as well. |
| int defaultListenerPrePersistCountBefore = DefaultListener.PRE_PERSIST_COUNT; |
| |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| |
| try { |
| MacBook macBook = new MacBook(); |
| macBook.setRam(8); |
| em.persist(macBook); |
| commitTransaction(em); |
| } catch (RuntimeException ex) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| closeEntityManager(em); |
| throw ex; |
| } |
| |
| closeEntityManager(em); |
| |
| int defaultListenerPrePersistCountAfter = DefaultListener.PRE_PERSIST_COUNT; |
| |
| assertFalse("The PrePersist callback method on DefaultListener was not called.", defaultListenerPrePersistCountBefore == defaultListenerPrePersistCountAfter); |
| } |
| |
| public void testSessionEventListenerOnBus() { |
| EntityManager em = createEntityManager(); |
| |
| try { |
| beginTransaction(em); |
| Bus bus = new Bus(); |
| // This string must not change ... session event listener will look |
| // for it and will create a new bus with description 'Listener test Bus2' |
| bus.setDescription("Listener test Bus1"); |
| em.persist(bus); |
| commitTransaction(em); |
| |
| // Should be able to find the bus created through the listener. |
| List results = em.createQuery("select object(bus) from Bus bus where bus.description = 'Listener test Bus2'").getResultList(); |
| assertTrue("Did not find the bus created by the session listener.", results.size() == 1); |
| } catch (RuntimeException ex) { |
| if (isTransactionActive(em)){ |
| rollbackTransaction(em); |
| } |
| |
| throw ex; |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| } |