@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
 @Override
 public void removeGeneralNodeDatumMetadata(Long nodeId, String sourceId) {
   GeneralNodeDatumMetadata meta =
       generalNodeDatumMetadataDao.get(new NodeSourcePK(nodeId, sourceId));
   if (meta != null) {
     generalNodeDatumMetadataDao.delete(meta);
   }
 }
 @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
 @Override
 public void storeGeneralNodeDatumMetadata(
     Long nodeId, String sourceId, GeneralDatumMetadata meta) {
   assert nodeId != null;
   assert sourceId != null;
   assert meta != null;
   NodeSourcePK pk = new NodeSourcePK(nodeId, sourceId);
   GeneralNodeDatumMetadata gdm = generalNodeDatumMetadataDao.get(pk);
   if (gdm == null) {
     gdm = new GeneralNodeDatumMetadata();
     gdm.setCreated(new DateTime());
     gdm.setId(pk);
     gdm.setMeta(meta);
   } else {
     gdm.setMeta(meta);
   }
   generalNodeDatumMetadataDao.store(gdm);
 }
 @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
 @Override
 public void addGeneralNodeDatumMetadata(Long nodeId, String sourceId, GeneralDatumMetadata meta) {
   assert nodeId != null;
   assert sourceId != null;
   assert meta != null;
   NodeSourcePK pk = new NodeSourcePK(nodeId, sourceId);
   GeneralNodeDatumMetadata gdm = generalNodeDatumMetadataDao.get(pk);
   GeneralDatumMetadata newMeta = meta;
   if (gdm == null) {
     gdm = new GeneralNodeDatumMetadata();
     gdm.setCreated(new DateTime());
     gdm.setId(pk);
     newMeta = meta;
   } else if (gdm.getMeta() != null && gdm.getMeta().equals(meta) == false) {
     newMeta = new GeneralDatumMetadata(gdm.getMeta());
     newMeta.merge(meta, true);
   }
   if (newMeta != null && newMeta.equals(gdm.getMeta()) == false) {
     // have changes, so persist
     gdm.setMeta(newMeta);
     generalNodeDatumMetadataDao.store(gdm);
   }
 }