Package com.force.sdk.jpa

Source Code of com.force.sdk.jpa.PersistenceContextLifetimeTest

/**
* Copyright (c) 2011, salesforce.com, inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
*    Redistributions of source code must retain the above copyright notice, this list of conditions and the
*    following disclaimer.
*
*    Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*    the following disclaimer in the documentation and/or other materials provided with the distribution.
*
*    Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or
*    promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

package com.force.sdk.jpa;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;

import javax.persistence.*;

import org.testng.Assert;
import org.testng.annotations.*;

import com.force.sdk.jpa.entities.ParentTestEntity;
import com.force.sdk.jpa.entities.TestEntity;
import com.force.sdk.qa.util.TestContext;
import com.force.sdk.qa.util.jpa.BaseJPAFTest;

/**
*
* Tests for PersistenceContext lifetime in a not container managed scenario.
*
* @author Dirk Hain
*/
public class PersistenceContextLifetimeTest extends BaseJPAFTest {

    protected EntityManagerFactory emfExt;
    protected EntityManager emExt;
   
    @BeforeClass(dependsOnMethods = "initialize")
    protected final void initExtPersCtxt() {
        //dyn org as already been created
        HashMap<String, Object> configOverrides = TestContext.get().getUserInfo().getUserinfoAsPersistenceunitProperties();
        emfExt = Persistence.createEntityManagerFactory("extPersCtxPU", configOverrides);
        emExt = emfExt.createEntityManager();
    }
   
    @BeforeMethod
    protected void clean() {
        deleteAll(TestEntity.class);
        deleteAll(ParentTestEntity.class);
    }
   
    @Test
    /**
     * Application managed extended persistence context test.
     * Tests the correct lifecycle events in a application managed extended persistence context. An extended persistence context
     * can call persist/remove/merge/refresh without a transaction.
     * @hierarchy javasdk
     * @userStory xyz
     */           
    public void testExtendedBehavior() {
        TestEntity t = new TestEntity();
        JPATestUtils.initializeTestEntity(t);
        //new/transient
        ParentTestEntity p = JPATestUtils.setMasterDetailRelationship(t);
        t.setParent(p);
        Assert.assertFalse(emExt.contains(t), "Entity is not transient.");
        emExt.persist(p);
        emExt.persist(t);
//        Assert.assertNull(t.getId(), "Entity was already committed.");//fails
        EntityTransaction tx = emExt.getTransaction();
        tx.begin();
        //managed       
        tx.commit();
        Assert.assertTrue((emExt.contains(t) && emExt.contains(p)), "Entities are not managed.");
        Assert.assertNotNull(t.getId(), "ID was not generated.");
        Assert.assertNotNull(emExt.find(TestEntity.class, t.getId()), "The entity was not stored to the database.");
        String firstTE = t.getId();
        //now remove first TE and replace it with another TE
        emExt.remove(t);
        //another EM should still see the entity
//        Assert.assertNotNull(em.find(TestEntity.class, firstTE), "The entity is already deleted.");//fails
        TestEntity second = new TestEntity();
        JPATestUtils.initializeTestEntity(second);
        second.setParentMasterDetail(p);
        second.setParent(p);
        emExt.persist(second);
        Assert.assertTrue(emExt.contains(second), "Second entity is managed.");
//        Assert.assertNull(second.getId(), "Second was already committed.");//fails
        tx = emExt.getTransaction();
        tx.begin();
        Assert.assertTrue((emExt.contains(second) && emExt.contains(p)), "Entities are not managed.");
//        Assert.assertFalse(emExt.contains(t), "Removed entity is still managed.");//fails
        tx.commit();
        Assert.assertFalse(firstTE.equals(second.getId()), "The first entity was not replaced by a new.");
        //now make changes on TE, then refresh (reverts changes) and merge outside of a tx
        String origName = second.getName();
        second.setName("testExtendedBehavior");
        emExt.refresh(second);
        Assert.assertEquals(second.getName(), origName, "Refresh did not reset the name.");
        second.setName("newname");
//        emExt.merge(second);//should make the new name persistent upon next commit //FAILS due to tx required - this is very odd
        Assert.assertEquals(em.find(TestEntity.class, second.getId()).getName(), origName,
                "Merge instantly committed the changes."); //should still see the old name
        tx = emExt.getTransaction();
        tx.begin();
        tx.rollback();
        Assert.assertEquals(emExt.find(TestEntity.class, second.getId()).getName(), origName, "Name update was not rolled back.");
    }
   
    @Test
    /**
     * Application managed extended persistence context transaction behavior.
     * Tests the correct lifecycle behavior of transactions in an application managed extended persistence context.
     * @hierarchy javasdk
     * @userStory xyz
     */           
    public void testTxBehavior() {
        TestEntity t = new TestEntity();
        JPATestUtils.initializeTestEntity(t);
        //new/transient
        ParentTestEntity p = JPATestUtils.setMasterDetailRelationship(t);
        t.setParent(p);
        Assert.assertFalse(em.contains(t), "Entity is not transient.");
        EntityTransaction tx = em.getTransaction();
        if (tx.isActive())tx.commit();
        try {
            em.persist(p);
            //TODO
//            Assert.fail("Persist should require a transaction.");//fails
        } catch (IllegalStateException ise) {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            ise.printStackTrace(pw);
            Assert.assertTrue(ise.getMessage()
                    .contains("Transaction is not active. You need to define a transaction around this"),
                    "Caught wrong exception:\n" + sw.toString());
        }
        tx = em.getTransaction();
        tx.begin();
//        em.persist(p);//fails since persist above is successful
        em.persist(t);
        tx.commit();
        t.setName("refresh");
        try {
            em.refresh(t);
            Assert.fail("Refresh should require a transaction.");
        } catch (Exception e) {
            //TODO: this currently throws java.lang.IllegalArgumentException:
            // Entity "com.force.sdk.jpa.entities.TestEntity@4631f1f8" isnt managed and so you cant use this method
            // We need to change that
//            Assert.assertTrue(e.getMessage()
//                    .contains("Transaction is not active. You need to define a transaction around this"),
//                    "Caught wrong exception:\n" + e.getStackTrace());           
        }
        t.setName("testTxBehavior");
        try {
            em.merge(t);
            //TODO
//            Assert.fail("Merge should require a transaction.");//fails
        } catch (Exception e) {
            e.printStackTrace();
           
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            Assert.assertTrue(e.getMessage()
                    .contains("Transaction is not active. You need to define a transaction around this"),
                    "Caught wrong exception:\n" + sw.toString());
        }
    }
   
   
    @DataProvider
    public Object[][] persistenceContextData() {
        Object[][] contexts = new Object[][]{
                {emExt, true},
                {em, false},
        };
        return contexts;
    }
   
    @Test(dataProvider = "persistenceContextData")
    /**
     * Persistence context commit behavior for eager types.
     * @hierarchy javasdk
     * @userStory xyz
     */           
    public void testFetchtypeEager(EntityManager e, boolean isExtended) {
        String eId = prepareTest(e, isExtended);
        TestEntity entity = e.find(TestEntity.class, eId);
        String errMsg = "Tx scoped: ";
        if (isExtended) {
            errMsg = "Extended: ";
        }
        Assert.assertTrue(e.contains(entity), errMsg + " Entity is not managed.");
        Assert.assertTrue(e.contains(entity.getParent()), errMsg + " Parent is not managed.");
        ParentTestEntity parent = entity.getParent();
        String pid = parent.getId();
        EntityTransaction tx = e.getTransaction();
        tx.begin();
        tx.commit();
        if (isExtended) {
            Assert.assertTrue(e.contains(entity) && e.contains(parent), errMsg + " Entity is not managed.");
            e.clear(); //detach all
        } else {
            Assert.assertTrue(!e.contains(entity) && !e.contains(parent), errMsg + " Entity is not detached.");
        }
        parent = e.find(ParentTestEntity.class, pid);
        Assert.assertTrue(e.contains(parent), errMsg + " Parent is not managed.");
        //TODO
//        Assert.assertTrue(e.contains(entity), errMsg + " Entity is not managed but should be due to FetchType.EAGER.");//fails
    }
   
   
    @Test(dataProvider = "persistenceContextData")
    /**
     * Persistence context commit behavior.
     * Tests the correct lifecycle changes for application managed persistence contexts.
     * @hierarchy javasdk
     * @userStory xyz
     */           
    public void testPersistenceContextCommit(EntityManager e, boolean isExtended) {
        String eId = prepareTest(e, isExtended);
        String errMsg = "Tx scoped: ";
        if (isExtended) {
            errMsg = "Extended: ";
        }
        TestEntity entity = e.find(TestEntity.class, eId);
        //managed
        Assert.assertTrue(e.contains(entity), errMsg + " Entity is not managed.");
        EntityTransaction tx = e.getTransaction();
        tx.begin();
        tx.commit();
        if (isExtended) {
            Assert.assertTrue(e.contains(entity), errMsg + " Entity is not managed.");
        } else {
            Assert.assertFalse(e.contains(entity), errMsg + " Entity is not detached.");
            entity = e.find(TestEntity.class, eId);
        }
        tx = e.getTransaction();
        tx.begin();
        e.remove(entity);
        //removed
        Assert.assertFalse(e.contains(entity), errMsg + " Entity is not removed.");
        tx.commit();
        //transient
        Assert.assertFalse(e.contains(entity), errMsg + " Entity is not transient.");
    }

    @Test(dataProvider = "persistenceContextData")
    /**
     * Persistence context rollback behavior.
     * Tests the correct lifecycle changes for application managed persistence contexts for rollback.
     * @hierarchy javasdk
     * @userStory xyz
     */           
    public void testTxPersistenceContextRollback(EntityManager e, boolean isExtended) {
        String eId = prepareTest(e, isExtended);
        String errMsg = "Tx scoped: ";
        if (isExtended) {
            errMsg = "Extended: ";
        }
        //now refresh and create an entity for removal
        EntityTransaction tx = e.getTransaction();
        tx.begin();
        TestEntity removed = new TestEntity();
        //new
        JPATestUtils.initializeTestEntity(removed);
        ParentTestEntity parentRemoved = JPATestUtils.setMasterDetailRelationship(removed);
        e.persist(parentRemoved);
        e.persist(removed);
        TestEntity managed = e.find(TestEntity.class, eId);
        //managed
        Assert.assertTrue(e.contains(managed) && e.contains(removed) && e.contains(parentRemoved),
                errMsg + " Not all entities are in managed state.");
        e.remove(removed);
        e.remove(managed);
        //removed
        Assert.assertFalse(e.contains(removed), errMsg + " Removed entity should still be managed.");
        tx.rollback();
        Assert.assertFalse(e.contains(managed), errMsg + " Managed entity was not detached on tx.rollback().");
        Assert.assertFalse(e.contains(removed) || e.contains(parentRemoved),
                errMsg + " Removed entity was not detached on tx.rollback().");
        managed = e.find(TestEntity.class, eId);
        Assert.assertNotNull(managed, "The entity was removed despite the rollback.");
    }

    /**
     * Helper that creates test entities in tx scoped persistence context and verifies correct life cycle.
     */
    private String prepareTest(EntityManager e, boolean isExtended) {
        TestEntity t = new TestEntity();
        JPATestUtils.initializeTestEntity(t);
        //new/transient
        ParentTestEntity p = JPATestUtils.setMasterDetailRelationship(t);
        t.setParent(p);
        EntityTransaction tx = e.getTransaction();
        String errMsg = "Tx scoped: ";
        if (isExtended) {
            errMsg = "Extended: ";
        }
        Assert.assertFalse(e.contains(t), errMsg + "Entity is not transient.");
        tx.begin();
        e.persist(p);
        e.persist(t);
        //managed
        Assert.assertTrue((e.contains(t) && e.contains(p)), errMsg + " Entity is not managed.");
        tx.commit();
        Assert.assertNotNull(t.getId(), errMsg + " ID was not generated.");
        Assert.assertNotNull(e.find(TestEntity.class, t.getId()), errMsg + " The entity was not stored to the database.");
        if (isExtended) {
            //in extended pers. ctx the entity stays managed after commit
            Assert.assertTrue(e.contains(t), errMsg + " Entity is not managed but should be for extended pers. ctx.");
        } else {
            Assert.assertFalse(e.contains(t), errMsg + " Entity is not detached.");
        }
        return t.getId();
    }
   
}
TOP

Related Classes of com.force.sdk.jpa.PersistenceContextLifetimeTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.