gr.interamerican.bo2.impl.open.hibernate.TestProxySessionPropagation.java Source code

Java tutorial

Introduction

Here is the source code for gr.interamerican.bo2.impl.open.hibernate.TestProxySessionPropagation.java

Source

/*******************************************************************************
 * Copyright (c) 2013 INTERAMERICAN PROPERTY AND CASUALTY INSURANCE COMPANY S.A. 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v3
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/copyleft/lesser.html
 * 
 * This library is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU Lesser General Public License for more details.
 ******************************************************************************/
package gr.interamerican.bo2.impl.open.hibernate;

import gr.interamerican.bo2.arch.PersistenceWorker;
import gr.interamerican.bo2.arch.exceptions.DataException;
import gr.interamerican.bo2.arch.exceptions.InitializationException;
import gr.interamerican.bo2.arch.exceptions.LogicException;
import gr.interamerican.bo2.arch.exceptions.UnexpectedException;
import gr.interamerican.bo2.impl.open.creation.Factory;
import gr.interamerican.bo2.impl.open.po.PoUtils;
import gr.interamerican.bo2.impl.open.runtime.AbstractBo2RuntimeCmd;
import gr.interamerican.bo2.test.def.posamples.Customer;
import gr.interamerican.bo2.test.def.posamples.Invoice;
import gr.interamerican.bo2.test.def.posamples.SamplesFactory;
import gr.interamerican.bo2.test.scenarios.DeleteInvoiceData;

import java.util.Date;

import org.hibernate.LockOptions;
import org.hibernate.Session;
import org.hibernate.proxy.HibernateProxy;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * Unit tests that demonstrate the cases where an initialized proxy
 * of entity B associated with a many-to-one relationship with no
 * cascade options with an entity A will not ontain a session when
 * reattaching A and will need special treatment.
 * 
 * This test case will use the following samples.
 * An Invoice has one InvoiceCustomer (one-to-one, cascade="all" association).
 * An InvoiceCustomer has a Customer (many-to-one, no cascade option association).
 * A Customer has a set of CustomerAddress (one-to-many, cascade="all,delete-orphan" association).
 */
public class TestProxySessionPropagation {

    /**
     * samples factory
     */
    private SamplesFactory factory = SamplesFactory.getBo2Factory();

    /**
     * Sample invoice no.
     */
    private String invoiceNo = "AAA"; //$NON-NLS-1$

    /**
     * Sample customer no.
     */
    private String customerNo = "No1"; //$NON-NLS-1$

    /**
     * Sample customer name.
     */
    private String customerName = "cName"; //$NON-NLS-1$

    /**
     * Sample invoice reference.
     */
    private Invoice invoice;

    /**
     * Placeholder for lastModified property of the Customer.
     */
    private Date customerLastModified;

    /**
     * Clear data and setup a sample Invoice. 
     * 
     * @throws UnexpectedException
     * @throws DataException
     * @throws LogicException
     */
    @Before
    public void before() throws UnexpectedException, DataException, LogicException {
        new AbstractBo2RuntimeCmd() {
            @Override
            public void work() throws LogicException, DataException, InitializationException, UnexpectedException {
                open(DeleteInvoiceData.class).execute();
                Customer c = factory.sampleCustomer("AAA"); //$NON-NLS-1$
                PersistenceWorker<Customer> pw = openPw(Customer.class);
                c.setCustomerNo(customerNo);
                c = pw.store(c);
                invoice = SamplesFactory.getBo2Factory().sampleInvoiceFull(2);
                invoice.setInvoiceNo(invoiceNo);
                invoice.getCustomer().setCustomer(c);
                PersistenceWorker<Invoice> ipw = openPw(Invoice.class);
                invoice = ipw.store(invoice);
            }
        }.execute();
    }

    /**
     * Demonstrates that an uninitialized Customer proxy will get
     * a Session instance when the Invoice is reattached and it will
     * be possible to initialize the CustomerAddress set. 
     * 
     * @throws LogicException 
     * @throws DataException 
     * @throws UnexpectedException 
     */
    @Test
    public void testUninitializedProxiesReattachOK() throws UnexpectedException, DataException, LogicException {
        new AbstractBo2RuntimeCmd() {
            @Override
            public void work() throws LogicException, DataException, InitializationException, UnexpectedException {
                invoice = Factory.create(Invoice.class);
                invoice.setInvoiceNo(invoiceNo);
                PersistenceWorker<Invoice> ipw = openPw(Invoice.class);
                invoice = ipw.read(invoice);
            }
        }.execute();

        new AbstractBo2RuntimeCmd() {
            @Override
            public void work() throws LogicException, DataException, InitializationException, UnexpectedException {
                PoUtils.reattach(invoice, getProvider());

                Customer c = invoice.getCustomer().getCustomer();
                Assert.assertTrue(c instanceof HibernateProxy);
                HibernateProxy cProxy = (HibernateProxy) c;
                Assert.assertTrue(cProxy.getHibernateLazyInitializer().isUninitialized());
                Assert.assertNotNull(cProxy.getHibernateLazyInitializer().getSession());
            }
        }.execute();

        new AbstractBo2RuntimeCmd() {
            @Override
            public void work() throws LogicException, DataException, InitializationException, UnexpectedException {
                PoUtils.reattach(invoice, getProvider());

                Customer c = invoice.getCustomer().getCustomer();
                Assert.assertTrue(c instanceof HibernateProxy);
                HibernateProxy cProxy = (HibernateProxy) c;
                Assert.assertTrue(cProxy.getHibernateLazyInitializer().isUninitialized());
                Assert.assertNotNull(cProxy.getHibernateLazyInitializer().getSession());

                c.getAddresses().size();
            }
        }.execute();

    }

    /**
     * Demonstrates that an initialized Customer proxy will not get
     * a Session instance when the Invoice is reattached and it will
     * be impossible to initialize the CustomerAddress set. 
     * 
     * @throws LogicException 
     * @throws DataException 
     * @throws UnexpectedException 
     */
    @Test
    public void testInitializedProxiesReattachOK() throws UnexpectedException, DataException, LogicException {
        new AbstractBo2RuntimeCmd() {
            @Override
            public void work() throws LogicException, DataException, InitializationException, UnexpectedException {
                invoice = Factory.create(Invoice.class);
                invoice.setInvoiceNo(invoiceNo);
                PersistenceWorker<Invoice> ipw = openPw(Invoice.class);
                invoice = ipw.read(invoice);
            }
        }.execute();

        new AbstractBo2RuntimeCmd() {
            @Override
            public void work() throws LogicException, DataException, InitializationException, UnexpectedException {
                PoUtils.reattach(invoice, getProvider());

                Customer c = invoice.getCustomer().getCustomer();
                Assert.assertTrue(c instanceof HibernateProxy);
                HibernateProxy cProxy = (HibernateProxy) c;
                Assert.assertTrue(cProxy.getHibernateLazyInitializer().isUninitialized());
                Assert.assertNotNull(cProxy.getHibernateLazyInitializer().getSession());
                c.getCustomerName();
                Assert.assertFalse(cProxy.getHibernateLazyInitializer().isUninitialized());
            }
        }.execute();

        new AbstractBo2RuntimeCmd() {
            @Override
            public void work() throws LogicException, DataException, InitializationException, UnexpectedException {
                PoUtils.reattach(invoice, getProvider());

                Customer c = invoice.getCustomer().getCustomer();
                Assert.assertTrue(c instanceof HibernateProxy);
                HibernateProxy cProxy = (HibernateProxy) c;
                Assert.assertFalse(cProxy.getHibernateLazyInitializer().isUninitialized());
                Assert.assertNotNull(cProxy.getHibernateLazyInitializer().getSession());

                c.getAddresses().size();
            }
        }.execute();

    }

    /**
     * Demonstrates that a many-to-one customer instance reattached with 
     * session.buildLockRequest(LockOptions.NONE).lock(customer) will not
     * have its modification record altered on the next session.flush, i.e.
     * no SQL associated with this entity will be sent to the database. 
     * 
     * @throws UnexpectedException
     * @throws DataException
     * @throws LogicException
     */
    @Test
    public void testManyToOneNoCascadeReattachedAreNotFlushed()
            throws UnexpectedException, DataException, LogicException {
        new AbstractBo2RuntimeCmd() {
            @Override
            public void work() throws LogicException, DataException, InitializationException, UnexpectedException {
                invoice = Factory.create(Invoice.class);
                invoice.setInvoiceNo(invoiceNo);
                PersistenceWorker<Invoice> ipw = openPw(Invoice.class);
                invoice = ipw.read(invoice);
            }
        }.execute();

        new AbstractBo2RuntimeCmd() {
            @Override
            public void work() throws LogicException, DataException, InitializationException, UnexpectedException {
                PoUtils.reattach(invoice, getProvider());

                Customer c = invoice.getCustomer().getCustomer();
                Assert.assertTrue(c instanceof HibernateProxy);
                HibernateProxy cProxy = (HibernateProxy) c;
                Assert.assertTrue(cProxy.getHibernateLazyInitializer().isUninitialized());
                Assert.assertNotNull(cProxy.getHibernateLazyInitializer().getSession());
                c.getCustomerName();
                Assert.assertFalse(cProxy.getHibernateLazyInitializer().isUninitialized());
            }
        }.execute();

        new AbstractBo2RuntimeCmd() {
            @Override
            public void work() throws LogicException, DataException, InitializationException, UnexpectedException {
                PoUtils.reattach(invoice, getProvider());

                Customer c = invoice.getCustomer().getCustomer();
                Assert.assertTrue(c instanceof HibernateProxy);
                HibernateProxy cProxy = (HibernateProxy) c;
                Assert.assertFalse(cProxy.getHibernateLazyInitializer().isUninitialized());
                Assert.assertNotNull(cProxy.getHibernateLazyInitializer().getSession());

                customerLastModified = c.getLastModified();

                Session s = getProvider().getResource("LOCALDB", HibernateSessionProvider.class) //$NON-NLS-1$
                        .getHibernateSession();
                s.buildLockRequest(LockOptions.NONE).lock(c);

                Assert.assertEquals(customerLastModified, c.getLastModified());

                Assert.assertNotNull(cProxy.getHibernateLazyInitializer().getSession());
                c.getAddresses().size();

                PersistenceWorker<Invoice> ipw = openPw(Invoice.class);
                ipw.store(invoice); //flush the session
            }
        }.execute();

        new AbstractBo2RuntimeCmd() {
            @Override
            public void work() throws LogicException, DataException, InitializationException, UnexpectedException {
                PersistenceWorker<Customer> cpw = openPw(Customer.class);
                Customer c = Factory.create(Customer.class);
                c.setCustomerNo(customerNo);
                c = cpw.read(c);
                Assert.assertEquals(customerLastModified, c.getLastModified());
            }
        }.execute();

    }

    /**
     * Demonstrates that a many-to-one customer instance reattached with 
     * session.buildLockRequest(LockOptions.NONE).lock(customer) will have
     * SQL sent on the next session.flush if it has been modified. 
     * 
     * @throws UnexpectedException
     * @throws DataException
     * @throws LogicException
     */
    @Test
    public void testDirtyManyToOneNoCascadeReattachedFlush()
            throws UnexpectedException, DataException, LogicException {
        new AbstractBo2RuntimeCmd() {
            @Override
            public void work() throws LogicException, DataException, InitializationException, UnexpectedException {
                invoice = Factory.create(Invoice.class);
                invoice.setInvoiceNo(invoiceNo);
                PersistenceWorker<Invoice> ipw = openPw(Invoice.class);
                invoice = ipw.read(invoice);
            }
        }.execute();

        new AbstractBo2RuntimeCmd() {
            @Override
            public void work() throws LogicException, DataException, InitializationException, UnexpectedException {
                PoUtils.reattach(invoice, getProvider());

                Customer c = invoice.getCustomer().getCustomer();
                Assert.assertTrue(c instanceof HibernateProxy);
                HibernateProxy cProxy = (HibernateProxy) c;
                Assert.assertTrue(cProxy.getHibernateLazyInitializer().isUninitialized());
                Assert.assertNotNull(cProxy.getHibernateLazyInitializer().getSession());
                c.getCustomerName();
                Assert.assertFalse(cProxy.getHibernateLazyInitializer().isUninitialized());
            }
        }.execute();

        new AbstractBo2RuntimeCmd() {
            @Override
            public void work() throws LogicException, DataException, InitializationException, UnexpectedException {
                PoUtils.reattach(invoice, getProvider());

                Customer c = invoice.getCustomer().getCustomer();
                Assert.assertTrue(c instanceof HibernateProxy);
                HibernateProxy cProxy = (HibernateProxy) c;
                Assert.assertFalse(cProxy.getHibernateLazyInitializer().isUninitialized());
                Assert.assertNotNull(cProxy.getHibernateLazyInitializer().getSession());

                customerLastModified = c.getLastModified();

                Session s = getProvider().getResource("LOCALDB", HibernateSessionProvider.class) //$NON-NLS-1$
                        .getHibernateSession();
                s.buildLockRequest(LockOptions.NONE).lock(c);

                Assert.assertEquals(customerLastModified, c.getLastModified());

                Assert.assertNotNull(cProxy.getHibernateLazyInitializer().getSession());
                c.getAddresses().size();
                c.setCustomerName(customerName); //make Customer dirty

                PersistenceWorker<Invoice> ipw = openPw(Invoice.class);
                ipw.store(invoice); //flush the session
            }
        }.execute();

        new AbstractBo2RuntimeCmd() {
            @Override
            public void work() throws LogicException, DataException, InitializationException, UnexpectedException {
                PersistenceWorker<Customer> cpw = openPw(Customer.class);
                Customer c = Factory.create(Customer.class);
                c.setCustomerNo(customerNo);
                c = cpw.read(c);
                Assert.assertEquals(customerName, c.getCustomerName());
            }
        }.execute();

    }

}