edu.harvard.med.screensaver.db.ProxyInitializationTest.java Source code

Java tutorial

Introduction

Here is the source code for edu.harvard.med.screensaver.db.ProxyInitializationTest.java

Source

// $HeadURL$
// $Id$
//
// Copyright  2006, 2010, 2011, 2012 by the President and Fellows of Harvard College.
//
// Screensaver is an open-source project developed by the ICCB-L and NSRB labs
// at Harvard Medical School. This software is distributed under the terms of
// the GNU General Public License.

package edu.harvard.med.screensaver.db;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.log4j.Logger;
import org.hibernate.Hibernate;
import org.joda.time.LocalDate;
import org.springframework.test.annotation.IfProfileValue;

import edu.harvard.med.screensaver.model.Volume;
import edu.harvard.med.screensaver.model.cherrypicks.CherryPickAssayPlate;
import edu.harvard.med.screensaver.model.cherrypicks.CherryPickLiquidTransfer;
import edu.harvard.med.screensaver.model.cherrypicks.CherryPickLiquidTransferStatus;
import edu.harvard.med.screensaver.model.cherrypicks.CherryPickRequest;
import edu.harvard.med.screensaver.model.cherrypicks.LabCherryPick;
import edu.harvard.med.screensaver.model.libraries.Copy;
import edu.harvard.med.screensaver.model.libraries.CopyUsageType;
import edu.harvard.med.screensaver.model.libraries.Library;
import edu.harvard.med.screensaver.model.libraries.PlateType;
import edu.harvard.med.screensaver.model.libraries.Well;
import edu.harvard.med.screensaver.model.screens.CherryPickScreening;
import edu.harvard.med.screensaver.model.screens.Screen;
import edu.harvard.med.screensaver.model.screens.ScreenType;
import edu.harvard.med.screensaver.model.users.AdministratorUser;
import edu.harvard.med.screensaver.model.users.LabHead;
import edu.harvard.med.screensaver.model.users.ScreeningRoomUser;
import edu.harvard.med.screensaver.test.AbstractSpringPersistenceTest;
import edu.harvard.med.screensaver.test.MakeDummyEntities;

/**
 * See <a href=
 * "http://forge.abcd.harvard.edu/gf/project/screensaver/tracker/?action=TrackerItemEdit&tracker_item_id=2516"
 * >[#2516]</a>
 */
@IfProfileValue(name = "demonstrate.hibernate.bugs", value = "true")
public class ProxyInitializationTest extends AbstractSpringPersistenceTest {

    private static final Logger log = Logger.getLogger(ProxyInitializationTest.class);

    @PersistenceContext
    protected EntityManager entityManager;

    protected void setUp() throws Exception {
        super.setUp();
        genericEntityDao.doInTransaction(new DAOTransaction() {
            @Override
            public void runTransaction() {
                Library library = MakeDummyEntities.makeDummyLibrary(1, ScreenType.RNAI, 1);
                Well well = library.getWells().iterator().next();
                Copy copy = library.createCopy((AdministratorUser) library.getCreatedBy(),
                        CopyUsageType.CHERRY_PICK_SOURCE_PLATES, "A");
                copy.findPlate(1000).withPlateType(PlateType.ABGENE).withWellVolume(new Volume(10));
                genericEntityDao.persistEntity(library);

                Screen screen = dataFactory.newInstance(Screen.class);
                screen.setFacilityId("1");
                screen.setLabHead(dataFactory.newInstance(LabHead.class));
                screen.setLeadScreener(dataFactory.newInstance(LabHead.class));
                screen.setScreenType(ScreenType.RNAI);
                CherryPickRequest cpr = screen.createCherryPickRequest(
                        dataFactory.newInstance(AdministratorUser.class),
                        dataFactory.newInstance(ScreeningRoomUser.class), new LocalDate());
                cpr.setTransferVolumePerWellApproved(new Volume(1));
                cpr.setRequestedBy(screen.getLeadScreener());
                LabCherryPick lcp = cpr.createScreenerCherryPick(well).createLabCherryPick(well);
                CherryPickAssayPlate cpap = cpr.createCherryPickAssayPlate(0, 0, PlateType.ABGENE);
                lcp.setAllocated(copy);
                lcp.setMapped(cpap, 0, 0);
                AdministratorUser admin1 = new AdministratorUser("Admin1", "User");
                CherryPickLiquidTransfer cplt = screen.createCherryPickLiquidTransfer(admin1,
                        screen.getLeadScreener(), new LocalDate(), CherryPickLiquidTransferStatus.SUCCESSFUL);
                cplt.addCherryPickAssayPlate(cpap);
                genericEntityDao.persistEntity(screen);
            }
        });
    }

    class TestTxn implements DAOTransaction {
        public CherryPickRequest _cpr;
        public CherryPickScreening _screening;

        @Override
        public void runTransaction() {
            log.info("initial session:" /* TODO */);
            ScreeningRoomUser originalPerformedBy = _cpr.getRequestedBy();
            log.info("original performedBy class=" + originalPerformedBy.getClass());
            //      Screen screen = genericEntityDao.reloadEntity(_cpr.getScreen());
            //      CherryPickRequest cpr = genericEntityDao.reloadEntity(_cpr);

            /* calling Hibernate.initialize does not fix the problem */
            //Hibernate.initialize(screen.getLeadScreener()); 

            /* calling genericEntityDao.findEntityById DOES fix the problem */
            //ScreeningRoomUser reloadedPerformedBy = genericEntityDao.findEntityById(ScreeningRoomUser.class, originalPerformedBy.getEntityId());

            /* this custom HQL fixes the problem */
            //ScreeningRoomUser reloadedPerformedBy = genericEntityDao.findEntitiesByHql(ScreeningRoomUser.class, "from ScreeningRoomUser x where x = ?", originalPerformedBy).get(0);

            /* this custom HQL, which is the same as that generated by the original reloadEntity() call, recreates the problem */
            //ScreeningRoomUser reloadedPerformedBy = genericEntityDao.findEntitiesByHql(ScreeningRoomUser.class, "from LabHead x where x.id = ?", originalPerformedBy.getEntityId()).get(0);

            /* this call which requests a ScreeningRoomUser type explicitly DOES fix the problem */
            //ScreeningRoomUser reloadedPerformedBy = genericEntityDao.findEntityById(ScreeningRoomUser.class, originalPerformedBy.getEntityId(), true);

            /* this call which requests a LabHead type explicitly does NOT fix the problem */
            //ScreeningRoomUser reloadedPerformedBy = genericEntityDao.findEntityById(LabHead.class, originalPerformedBy.getEntityId(), true);

            /*
             * the original code, that causes the problem; returns a non-proxy instance, and so differs from
             * Screen.leadScreener
             */
            ScreeningRoomUser reloadedPerformedBy = genericEntityDao.reloadEntity(originalPerformedBy);

            /*
             * if we load the performedBy entity before the screen and cherryPickRequest, then these latter two can be loaded
             * with the non-proxy instance, which fixes the problem
             */
            Screen screen = genericEntityDao.reloadEntity(_cpr.getScreen());
            CherryPickRequest cpr = genericEntityDao.reloadEntity(_cpr);

            assertSame(screen.getLeadScreener(), reloadedPerformedBy);
            assertSame(cpr.getRequestedBy(), reloadedPerformedBy);

            log.info("pre-eager-fetch cpr requestedBy initialized: "
                    + Hibernate.isInitialized(cpr.getRequestedBy()));
            log.info("pre-eager-fetch screen lead screener initialized: "
                    + Hibernate.isInitialized(screen.getLeadScreener()));
            log.info("pre-eager-fetch session:" /* TODO */);

            genericEntityDao.needReadOnly(screen, Screen.leadScreener);
            log.info("post-eager-fetch cpr requestedBy initialized: "
                    + Hibernate.isInitialized(cpr.getRequestedBy()));
            log.info("post-eager-fetch screen lead screener initialized: "
                    + Hibernate.isInitialized(screen.getLeadScreener()));
            log.info("post-eager-fetch session:" /* TODO */);
            assertTrue(Hibernate.isInitialized(screen.getLeadScreener()));
            assertTrue(Hibernate.isInitialized(cpr.getRequestedBy()));
        }
    };

    public void testInitializeExtantProxy() {
        TestTxn txn = new TestTxn();

        txn._cpr = genericEntityDao
                .findAllEntitiesOfType(CherryPickRequest.class, true, CherryPickRequest.requestedBy).get(0);
        log.info("pre-txn cpr requestedBy initialized: " + Hibernate.isInitialized(txn._cpr.getRequestedBy()));
        log.info("pre-txn cpr requestedBy: " + txn._cpr.getRequestedBy().getClass() + " "
                + txn._cpr.getRequestedBy().getEntityId());
        genericEntityDao.doInTransaction(txn);

        //    log.info("post txn screening.screen.leadScreener=" + txn._screening.getScreen().getLeadScreener().getClass() + " " +
        //      txn._screening.getScreen().getLeadScreener());

        //txn._cpr.getRequestedBy().getLastName();
        //    txn._screen.getLeadScreener().getScreensaverUserId();
        //txn._screen.getLeadScreener().getEntityId();
    }
}