@Test
  public final void testDeleteWithPropertiesButParentPreserved() {
    final IExternalDataDAO externalDataDAO = daoFactory.getExternalDataDAO();
    final ExternalDataPE deletedData = findExternalData(CHILD_CODE);

    // Deleted data set should have all collections which prevent it from deletion empty.
    assertTrue(deletedData.getChildren().isEmpty());

    // delete
    externalDataDAO.delete(deletedData);

    // test successful deletion of data set
    assertNull(externalDataDAO.tryGetByTechId(TechId.create(deletedData)));

    // test successful deletion of data set properties
    assertFalse(deletedData.getProperties().isEmpty());
    List<EntityTypePropertyTypePE> retrievedPropertyTypes =
        daoFactory
            .getEntityPropertyTypeDAO(EntityKind.DATA_SET)
            .listEntityPropertyTypes(deletedData.getEntityType());
    for (DataSetPropertyPE property : deletedData.getProperties()) {
      int index = retrievedPropertyTypes.indexOf(property.getEntityTypePropertyType());
      EntityTypePropertyTypePE retrievedPropertyType = retrievedPropertyTypes.get(index);
      assertFalse(retrievedPropertyType.getPropertyValues().contains(property));
    }

    // deleted sample had parent connected that should not have been deleted
    // NOTE: somehow cannot get parents even though connection is the same as with children
    // DataPE parent = deletedData.tryGetParent();
    // assertNotNull(parent);
    // assertNotNull(externalDataDAO.tryGetByTechId(new TechId(HibernateUtils.getId(parent))));
    findExternalData(PARENT_CODE);
  }
  @Test
  public void testCreateDataSetWithNoSample() {
    IExternalDataDAO externalDataDAO = daoFactory.getExternalDataDAO();
    String dataSetCode = daoFactory.getPermIdDAO().createPermId();
    ExternalDataPE externalData = createExternalData(dataSetCode, null);
    externalDataDAO.createDataSet(externalData);

    ExternalDataPE dataSet = (ExternalDataPE) externalDataDAO.tryToFindDataSetByCode(dataSetCode);
    assertDataEqual(externalData, dataSet);
  }
  @Test
  public final void testListExternalData() {
    testCreateDataSetWithSample();
    final IExternalDataDAO externalDataDAO = daoFactory.getExternalDataDAO();
    List<ExternalDataPE> list = externalDataDAO.listExternalData(pickASample());

    assertEquals(1, list.size());
    ExternalDataPE dataSet = list.get(0);
    assertEquals("abcd", dataSet.getLocation());
    assertEquals(BooleanOrUnknown.U, dataSet.getComplete());
  }
  @Test(expectedExceptions = DataIntegrityViolationException.class)
  public final void testDeleteFailWithChildrenDatasets() {
    final IExternalDataDAO externalDataDAO = daoFactory.getExternalDataDAO();
    final ExternalDataPE deletedData = findExternalData(PARENT_CODE);

    // Deleted data set should have 'child' data sets which prevent it from deletion.
    assertFalse(deletedData.getChildren().isEmpty());

    // delete
    externalDataDAO.delete(deletedData);
  }
  @Test
  public void testUpdateOfDataSetFailWithSampleConnectedWhenThereIsParent() {
    final IExternalDataDAO externalDataDAO = daoFactory.getExternalDataDAO();

    // try to update dataset connected with a parent - connecting with a sample should fail
    final ExternalDataPE dataSetConnectedWithParent = findExternalData(CHILD_CODE);
    assertFalse(dataSetConnectedWithParent.getParents().isEmpty());
    dataSetConnectedWithParent.setSampleAcquiredFrom(pickASample());
    externalDataDAO.updateDataSet(dataSetConnectedWithParent);

    assertCommitFailsWithBothSampleAndParentConnectionForDataSet(CHILD_CODE);
  }
  @Test
  public void testUpdateOfDataSetFailWithParentAddedWhenIsSampleConnected() {
    final IExternalDataDAO externalDataDAO = daoFactory.getExternalDataDAO();

    // try to update dataset connected with a sample - adding a parent should fail
    final ExternalDataPE dataSetConnectedWithSample = findExternalData(PARENT_CODE);
    assertNotNull(dataSetConnectedWithSample.tryGetSample());
    final ExternalDataPE anotherDataSet = findExternalData("20081105092159111-1");
    dataSetConnectedWithSample.addParent(anotherDataSet);
    externalDataDAO.updateDataSet(dataSetConnectedWithSample);

    assertCommitFailsWithBothSampleAndParentConnectionForDataSet(PARENT_CODE);
  }
  @Test
  public void testCreateDataSetFailWithBothSampleAndParent() {
    final IExternalDataDAO externalDataDAO = daoFactory.getExternalDataDAO();

    // try to create a dataset connected with a sample and a parent at the same time
    final String dataSetCode = daoFactory.getPermIdDAO().createPermId();
    final SamplePE sample = pickASample();
    ExternalDataPE parentData = findExternalData(PARENT_CODE);
    ExternalDataPE externalData = createExternalData(dataSetCode, sample);
    externalData.addParent(parentData);
    externalDataDAO.createDataSet(externalData);

    assertCommitFailsWithBothSampleAndParentConnectionForDataSet(dataSetCode);
  }
  @Test
  public void testUpdateDataSetAquiredFromSample() {
    IExternalDataDAO externalDataDAO = daoFactory.getExternalDataDAO();
    DataPE data = new DataPE();
    String dataSetCode = daoFactory.getPermIdDAO().createPermId();
    data.setCode(dataSetCode);
    data.setDataSetType(getDataSetType(DataSetTypeCode.UNKNOWN));
    data.setExperiment(pickAnExperiment());
    data.setSampleAcquiredFrom(pickASample());
    data.setPlaceholder(true);
    data.setDataStore(pickADataStore());
    data.setModificationDate(new Date());
    externalDataDAO.createDataSet(data);

    ExternalDataPE externalData = new ExternalDataPE();
    externalData.setId(externalDataDAO.tryToFindDataSetByCode(dataSetCode).getId());
    externalData.setCode(dataSetCode);
    externalData.setDataSetType(getDataSetType(DataSetTypeCode.UNKNOWN));
    externalData.setDataStore(pickADataStore());
    externalData.setExperiment(pickAnExperiment());
    externalData.setSampleAcquiredFrom(pickASample());
    externalData.setFileFormatType(pickAFileFormatType());
    externalData.setLocatorType(pickALocatorType());
    externalData.setLocation("abcd");
    externalData.setComplete(BooleanOrUnknown.U);
    externalData.setStorageFormatVocabularyTerm(pickAStorageFormatVocabularyTerm());
    externalData.setPlaceholder(true);
    final Date modificationTimestamp = data.getModificationDate();
    externalData.setModificationDate(modificationTimestamp);
    externalDataDAO.updateDataSet(externalData);

    ExternalDataPE dataSet = (ExternalDataPE) externalDataDAO.tryToFindDataSetByCode(dataSetCode);
    assertEquals(externalData.getCode(), dataSet.getCode());
    assertEquals(externalData.getDataSetType(), dataSet.getDataSetType());
    assertEquals(externalData.getExperiment(), dataSet.getExperiment());
    assertEquals(externalData.getFileFormatType(), dataSet.getFileFormatType());
    assertEquals(externalData.getLocatorType(), dataSet.getLocatorType());
    assertEquals(externalData.getLocation(), dataSet.getLocation());
    assertEquals(externalData.getComplete(), dataSet.getComplete());
    assertEquals(externalData.getStorageFormat(), dataSet.getStorageFormat());
    assertEquals(externalData.isPlaceholder(), dataSet.isPlaceholder());
    assertEquals(externalData.isMeasured(), dataSet.isMeasured());
    assertFalse(externalData.getModificationDate().equals(modificationTimestamp));
  }
  @Test
  public void testUpdateDataSetWithParent() {
    final IExternalDataDAO externalDataDAO = daoFactory.getExternalDataDAO();

    // try to add a parent to a data set that already had one
    final ExternalDataPE dataSetConnectedWithParent = findExternalData(CHILD_CODE);
    assertFalse(dataSetConnectedWithParent.getParents().isEmpty());
    final ExternalDataPE anotherDataSet = findExternalData("20081105092159111-1");
    dataSetConnectedWithParent.addParent(anotherDataSet);
    externalDataDAO.updateDataSet(dataSetConnectedWithParent);

    ExternalDataPE dataSet = (ExternalDataPE) externalDataDAO.tryToFindDataSetByCode(CHILD_CODE);
    assertEquals(dataSetConnectedWithParent.getParents().size(), dataSet.getParents().size());
    Set<DataPE> extractedParents = dataSet.getParents();
    for (DataPE parent : dataSetConnectedWithParent.getParents()) {
      assertTrue(extractedParents.contains(parent));
    }
    assertTrue(extractedParents.contains(anotherDataSet));
  }