// $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 java.io.Serializable; import java.util.HashMap; import java.util.List; import java.util.Map; import com.google.common.collect.Sets; import org.apache.log4j.Logger; import org.hibernate.LazyInitializationException; import org.hibernate.Session; import org.joda.time.LocalDate; import edu.harvard.med.screensaver.test.AbstractSpringPersistenceTest; import edu.harvard.med.screensaver.test.MakeDummyEntities; import edu.harvard.med.screensaver.io.screenresults.ScreenResultParserTest; import edu.harvard.med.screensaver.model.AbstractEntity; import edu.harvard.med.screensaver.model.Entity; import edu.harvard.med.screensaver.model.activities.Activity; import edu.harvard.med.screensaver.model.activities.AdministrativeActivity; import edu.harvard.med.screensaver.model.activities.AdministrativeActivityType; import edu.harvard.med.screensaver.model.libraries.CopyUsageType; import edu.harvard.med.screensaver.model.libraries.Gene; import edu.harvard.med.screensaver.model.libraries.Library; import edu.harvard.med.screensaver.model.libraries.LibraryType; import edu.harvard.med.screensaver.model.libraries.LibraryWellType; import edu.harvard.med.screensaver.model.libraries.PlateSize; import edu.harvard.med.screensaver.model.libraries.ReagentVendorIdentifier; import edu.harvard.med.screensaver.model.libraries.SilencingReagent; import edu.harvard.med.screensaver.model.libraries.SilencingReagentType; import edu.harvard.med.screensaver.model.libraries.Well; import edu.harvard.med.screensaver.model.libraries.WellKey; import edu.harvard.med.screensaver.model.screenresults.DataColumn; import edu.harvard.med.screensaver.model.screenresults.ScreenResult; import edu.harvard.med.screensaver.model.screens.LabActivity; 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; public class GenericEntityDAOTest extends AbstractSpringPersistenceTest { private static final Logger log = Logger.getLogger(GenericEntityDAOTest.class); private AbstractEntity _anEntity; private AdministratorUser _adminUser; // public instance methods @Override protected void setUp() throws Exception { super.setUp(); _adminUser = new AdministratorUser("Admin", "User"); _anEntity = new Library(_adminUser, "Library Name", "libName", ScreenType.SMALL_MOLECULE, LibraryType.COMMERCIAL, 1, 1, PlateSize.WELLS_384); } @SuppressWarnings("unchecked") public void testPersistAndFindAllOfType() { genericEntityDao.saveOrUpdateEntity(_anEntity); List<AbstractEntity> result = (List<AbstractEntity>) genericEntityDao.findAllEntitiesOfType(_anEntity.getEntityClass()); assertEquals(result.size(), 1); AbstractEntity e = result.get(0); e.isEquivalent(_anEntity); } public void testFindEntityById() { genericEntityDao.saveOrUpdateEntity(_anEntity); Serializable id = _anEntity.getEntityId(); Entity e = genericEntityDao.findEntityById(_anEntity.getEntityClass(), id); assertEquals(_anEntity, e); Entity e2 = genericEntityDao.findEntityById(_anEntity.getEntityClass(), new Integer(-1)); assertEquals(null, e2); } public void testFindEntitiesByProperties() { final DataColumn[] cols = new DataColumn[4]; genericEntityDao.doInTransaction(new DAOTransaction() { public void runTransaction() { ScreenResult screenResult = ScreenResultParserTest.makeScreenResult(); cols[0] = screenResult.createDataColumn("col0"); cols[0].makeDerived("", Sets.<DataColumn>newHashSet()); cols[0].forPhenotype("Mouse"); cols[1] = screenResult.createDataColumn("col1"); cols[1].forPhenotype("Mouse"); cols[2] = screenResult.createDataColumn("col2"); cols[2].makeDerived("", Sets.<DataColumn>newHashSet()); cols[2].forPhenotype("Mouse"); cols[3] = screenResult.createDataColumn("col3"); cols[3].makeDerived("", Sets.<DataColumn>newHashSet()); cols[3].forPhenotype("Human"); genericEntityDao.saveOrUpdateEntity(screenResult.getScreen().getLeadScreener()); genericEntityDao.saveOrUpdateEntity(screenResult.getScreen().getLabHead()); genericEntityDao.saveOrUpdateEntity(screenResult.getScreen()); genericEntityDao.saveOrUpdateEntity(cols[0]); } }); genericEntityDao.doInTransaction(new DAOTransaction() { public void runTransaction() { Map<String,Object> queryProperties = new HashMap<String,Object>(); queryProperties.put("derived", true); queryProperties.put("assayPhenotype", "Mouse"); List<DataColumn> entities = genericEntityDao.findEntitiesByProperties( DataColumn.class, queryProperties); assertEquals(2, entities.size()); for (DataColumn dataColumn : entities) { assertTrue( dataColumn.getName().equals("col0") || dataColumn.getName().equals("col2")); assertEquals(true, dataColumn.isDerived()); assertEquals("Mouse", dataColumn.getAssayPhenotype()); } } }); } public void testFindEntityByProperties() { final Library[] expectedLibrary = new Library[1]; genericEntityDao.doInTransaction(new DAOTransaction() { public void runTransaction() { expectedLibrary[0] = new Library(_adminUser, "ln1", "sn1", ScreenType.SMALL_MOLECULE, LibraryType.NATURAL_PRODUCTS, 1, 50, PlateSize.WELLS_384); genericEntityDao.saveOrUpdateEntity(expectedLibrary[0]); } }); genericEntityDao.doInTransaction(new DAOTransaction() { public void runTransaction() { Map<String,Object> props = new HashMap<String,Object>(); props.put("startPlate", 1); props.put("endPlate", 50); Library actualLibrary = genericEntityDao.findEntityByProperties(Library.class, props); assertTrue(expectedLibrary[0].isEquivalent(actualLibrary)); } }); } @SuppressWarnings("unchecked") public void testFindEntitiesByProperty1() { genericEntityDao.saveOrUpdateEntity(_anEntity); List<AbstractEntity> result = (List<AbstractEntity>) genericEntityDao.findAllEntitiesOfType(_anEntity.getEntityClass()); assertEquals(1, result.size()); assertEquals(_anEntity, result.get(0)); result = (List<AbstractEntity>) genericEntityDao.findEntitiesByProperty(_anEntity.getEntityClass(), "shortName", "something other than ID"); assertEquals(0, result.size()); } public void testFindEntitiesByProperty2() { genericEntityDao.mergeEntity(new Library(_adminUser, "ln1", "sn1", ScreenType.SMALL_MOLECULE, LibraryType.NATURAL_PRODUCTS, 1, 50, PlateSize.WELLS_384)); genericEntityDao.mergeEntity(new Library(_adminUser, "ln2", "sn2", ScreenType.SMALL_MOLECULE, LibraryType.NATURAL_PRODUCTS, 51, 100, PlateSize.WELLS_384)); genericEntityDao.mergeEntity(new Library(_adminUser, "ln3", "sn3", ScreenType.SMALL_MOLECULE, LibraryType.ACADEMIC_COLLECTION, 101, 150, PlateSize.WELLS_384)); genericEntityDao.mergeEntity(new Library(_adminUser, "ln4", "sn4", ScreenType.SMALL_MOLECULE, LibraryType.NATURAL_PRODUCTS, 151, 200, PlateSize.WELLS_384)); genericEntityDao.mergeEntity(new Library(_adminUser, "ln5", "sn5", ScreenType.SMALL_MOLECULE, LibraryType.ACADEMIC_COLLECTION, 201, 250, PlateSize.WELLS_384)); assertEquals(3, genericEntityDao.findEntitiesByProperty(Library.class, "libraryType", LibraryType.NATURAL_PRODUCTS).size()); assertEquals(2, genericEntityDao.findEntitiesByProperty(Library.class, "libraryType", LibraryType.ACADEMIC_COLLECTION).size()); assertEquals(0, genericEntityDao.findEntitiesByProperty(Library.class, "libraryType", LibraryType.COMMERCIAL).size()); } public void testFindEntitybyProperty() { genericEntityDao.saveOrUpdateEntity(_anEntity); AbstractEntity e = genericEntityDao.findEntityByProperty(_anEntity.getClass(), "shortName", "libName"); assertEquals(_anEntity, e); AbstractEntity e2 = genericEntityDao.findEntityByProperty(_anEntity.getClass(), "shortName", "not libName"); assertNull(e2); } public void testFindEntitiesByPropertyWithInflation() { final Library[] expectedLibrary = new Library[1]; genericEntityDao.doInTransaction(new DAOTransaction() { public void runTransaction() { expectedLibrary[0] = new Library(_adminUser, "ln1", "sn1", ScreenType.RNAI, LibraryType.COMMERCIAL, 1, 50, PlateSize.WELLS_384); expectedLibrary[0].createContentsVersion(_adminUser); Well well1 = expectedLibrary[0].createWell(new WellKey(1, "A01"), LibraryWellType.EXPERIMENTAL); SilencingReagent reagent1 = well1.createSilencingReagent(new ReagentVendorIdentifier("vendor", "1a01"), SilencingReagentType.SIRNA, "AAAA"); reagent1.getVendorGene(). withGeneName("ANT1"). withEntrezgeneSymbol("ENTREZ-ANT1"). withEntrezgeneId(1). withSpeciesName("Human"). withGenbankAccessionNumber("GBAN1"); Well well2 = expectedLibrary[0].createWell(new WellKey(2, "A01"), LibraryWellType.EXPERIMENTAL); SilencingReagent reagent2 = well2.createSilencingReagent(new ReagentVendorIdentifier("vendor", "2a01"), SilencingReagentType.SIRNA, "CCCC"); reagent2.getVendorGene(). withGeneName("ANT2"). withEntrezgeneSymbol("ENTREZ-ANT2"). withEntrezgeneId(2). withSpeciesName("Human"). withGenbankAccessionNumber("GBAN2"); Well well3 = expectedLibrary[0].createWell(new WellKey(3, "A01"), LibraryWellType.EXPERIMENTAL); SilencingReagent reagent3 = well3.createSilencingReagent(new ReagentVendorIdentifier("vendor", "3a01"), SilencingReagentType.SIRNA, "TTTT"); reagent3.getVendorGene(). withGeneName("ANT3"). withEntrezgeneSymbol("ENTREZ-ANT3"). withEntrezgeneId(3). withSpeciesName("Human"). withGenbankAccessionNumber("GBAN3"); expectedLibrary[0].getLatestContentsVersion().release(new AdministrativeActivity(_adminUser, new LocalDate(), AdministrativeActivityType.LIBRARY_CONTENTS_VERSION_RELEASE)); expectedLibrary[0].createCopy(_adminUser, CopyUsageType.LIBRARY_SCREENING_PLATES, "copy1"); expectedLibrary[0].createCopy(_adminUser, CopyUsageType.LIBRARY_SCREENING_PLATES, "copy2"); expectedLibrary[0].createCopy(_adminUser, CopyUsageType.LIBRARY_SCREENING_PLATES, "copy3"); genericEntityDao.saveOrUpdateEntity(expectedLibrary[0]); } }); final Library[] actualLibrary = new Library[1]; genericEntityDao.doInTransaction(new DAOTransaction() { public void runTransaction() { actualLibrary[0] = genericEntityDao.findEntityByProperty(Library.class, "startPlate", 1, false, Library.wells.to(Well.latestReleasedReagent).to(SilencingReagent.vendorGenes).to(Gene.genbankAccessionNumbers)); assertTrue(expectedLibrary[0].isEquivalent(actualLibrary[0])); } }); try { assertEquals("inflated wells", 3, actualLibrary[0].getWells().size()); int i = 1; for (Well well : actualLibrary[0].getWells()) { assertEquals("inflated well", "A01", well.getWellName()); assertEquals("inflated silencing reagent", new String[] { "AAAA", "CCCC", "TTTT" }[i - 1], well.<SilencingReagent>getLatestReleasedReagent().getSequence()); assertEquals("inflated gene", "ANT" + i, well.<SilencingReagent>getLatestReleasedReagent().getVendorGene().getGeneName()); assertEquals("inflated genbankAccessionNumbers", "GBAN" + i, well.<SilencingReagent>getLatestReleasedReagent().getVendorGene().getGenbankAccessionNumbers().iterator().next()); ++i; } } catch (Exception e) { fail("inflation failed"); } try { actualLibrary[0].getCopies().iterator(); fail("copies inflated unexpectedly"); } catch (Exception e) { // pass } } public void testEntityInflation() { genericEntityDao.doInTransaction(new DAOTransaction() { public void runTransaction() { Screen screen = MakeDummyEntities.makeDummyScreen(1); ScreeningRoomUser labMember = new ScreeningRoomUser("Lab", "Member"); labMember.setLab(screen.getLabHead().getLab()); screen.addKeyword("keyword1"); screen.addKeyword("keyword2"); genericEntityDao.saveOrUpdateEntity(labMember); genericEntityDao.saveOrUpdateEntity(screen.getLeadScreener()); genericEntityDao.saveOrUpdateEntity(screen.getLabHead()); genericEntityDao.saveOrUpdateEntity(screen); } }); Screen screen = genericEntityDao.findEntityByProperty(Screen.class, Screen.facilityId.getPropertyName(), "1"); screen = new EntityInflator<Screen>(genericEntityDao, screen, true).need(Screen.keywords).need(Screen.labHead.to(LabHead.labMembers)).inflate(); // note: the following assertions must be made outside of a txn try { assertEquals("keywords size", 2, screen.getKeywords().size()); assertEquals("labHead last name", "Head_1", screen.getLabHead().getLastName()); assertEquals("labHead.labMembers size", 1, screen.getLabHead().getLab().getLabMembers().size()); assertEquals("labHead.labMembers[0].lastName", "Member", screen.getLabHead().getLab().getLabMembers().iterator().next().getLastName()); } catch (LazyInitializationException e) { e.printStackTrace(); fail("screen relationships was not inflated: " + e); } try { screen.getCollaborators().iterator().next(); fail("expected LazyInitializationException for screen.collaborators access"); } catch (LazyInitializationException e) {} } /** * Tests that reloadEntity() will eager fetch any specified relationships, * even if the entity is already managed by the current Hibernate session in * which reloadEntity() is called. */ public void testReloadOfManagedEntityEagerFetchesRequestedRelationships() { genericEntityDao.doInTransaction(new DAOTransaction() { public void runTransaction() { Screen screen = MakeDummyEntities.makeDummyScreen(1); screen.createLibraryScreening(_adminUser, screen.getLeadScreener(), new LocalDate()); genericEntityDao.persistEntity(screen); } }); class Txn implements DAOTransaction { //Screen screen; LabActivity activity; public void runTransaction() { //screen = genericEntityDao.findEntityByProperty(Screen.class, Screen.facilityId.getPropertyName(), "1"); //screen = genericEntityDao.reloadEntity(screen, true, "leadScreener"); activity = genericEntityDao.findEntityByProperty(LabActivity.class, "dateOfActivity", new LocalDate()); activity = genericEntityDao.reloadEntity(activity, true, Activity.performedBy.castToSubtype(LabActivity.class)); } }; Txn txn = new Txn(); genericEntityDao.doInTransaction(txn); //txn.screen.getLeadScreener().getFullNameLastFirst(); // no LazyInitExc txn.activity.getPerformedBy().getFullNameLastFirst(); // no LazyInitExc try { //txn.screen.getLabHead().getFullNameLastFirst(); txn.activity.getScreen().getTitle(); fail("expected LazyInitializationException on screen.getLabHead()"); } catch (LazyInitializationException e) {} } public void testFlushAndClearSession() { genericEntityDao.runQuery(new Query() { public List execute(Session session) { Library library = new Library(_adminUser, "library", "library", ScreenType.SMALL_MOLECULE, LibraryType.COMMERCIAL, 1, 1, PlateSize.WELLS_384); library.createWell(new WellKey(1, "A01"), LibraryWellType.EMPTY); genericEntityDao.saveOrUpdateEntity(library); genericEntityDao.flush(); assertTrue(session.contains(library)); assertEquals(3, session.getStatistics().getEntityCount()); assertEquals(library.getLibraryId(), session.getIdentifier(library)); genericEntityDao.clear(); assertEquals(0, session.getStatistics().getEntityCount()); assertFalse(session.contains(library)); return null; } }); assertNotNull(genericEntityDao.findEntityByProperty(Library.class, "libraryName", "library")); assertNotNull(genericEntityDao.findEntityById(Well.class, "00001:A01")); } public void testDistinctPropertyValues() { ScreeningRoomUser user1 = new ScreeningRoomUser("A", "D"); user1.setLoginId("AD"); ScreeningRoomUser user2 = new ScreeningRoomUser("A", "B"); ScreeningRoomUser user3 = new ScreeningRoomUser("B", "C"); ScreeningRoomUser user4 = new ScreeningRoomUser("C", "D"); genericEntityDao.persistEntity(user1); genericEntityDao.persistEntity(user2); genericEntityDao.persistEntity(user3); genericEntityDao.persistEntity(user4); assertEquals(Sets.newHashSet("A", "B", "C"), genericEntityDao.findDistinctPropertyValues(ScreeningRoomUser.class, "firstName")); assertEquals(Sets.newHashSet("B", "C", "D"), genericEntityDao.findDistinctPropertyValues(ScreeningRoomUser.class, "lastName")); assertEquals("nulls ignored in distinct values", Sets.newHashSet("AD"), genericEntityDao.findDistinctPropertyValues(ScreeningRoomUser.class, "loginId")); } }