/**
   * Method saving a poi and all the associated foreign collections without transaction management.
   *
   * <p>Do not call the DAO directly to save a poi, use this method.
   *
   * @param poi The poi to save
   * @return The saved poi
   * @see #savePoi(Poi)
   */
  private Poi savePoiNoTransaction(Poi poi) {
    List<PoiTag> poiTagsToRemove = poiTagDao.queryByPoiId(poi.getId());
    poiTagsToRemove.removeAll(poi.getTags());
    for (PoiTag poiTag : poiTagsToRemove) {
      poiTagDao.delete(poiTag);
    }

    List<PoiNodeRef> poiNodeRefsToRemove = poiNodeRefDao.queryByPoiId(poi.getId());
    poiNodeRefsToRemove.removeAll(poi.getNodeRefs());
    for (PoiNodeRef poiNodeRef : poiNodeRefsToRemove) {
      poiNodeRefDao.delete(poiNodeRef);
    }

    poiDao.createOrUpdate(poi);

    if (poi.getTags() != null) {
      for (PoiTag poiTag : poi.getTags()) {
        poiTag.setPoi(poi);
        poiTagDao.createOrUpdate(poiTag);
      }
    }

    if (poi.getNodeRefs() != null) {
      for (PoiNodeRef poiNodeRef : poi.getNodeRefs()) {
        poiNodeRef.setPoi(poi);
        poiNodeRefDao.createOrUpdate(poiNodeRef);
      }
    }

    return poi;
  }
  public void onEventAsync(PleaseLoadPoisToUpdateEvent event) {
    List<Poi> updatedPois = poiDao.queryForAllUpdated();
    List<Poi> newPois = poiDao.queryForAllNew();
    List<Poi> toDeletePois = poiDao.queryToDelete();
    List<PoiNodeRef> wayPoiNodeRef = poiNodeRefDao.queryAllToUpdate();
    List<PoiUpdateWrapper> allPois = new ArrayList<>();

    for (Poi p : updatedPois) {
      allPois.add(
          new PoiUpdateWrapper(
              true,
              p,
              poiDao.queryForId(p.getOldPoiId()),
              null,
              PoiUpdateWrapper.PoiAction.UPDATE));
    }
    for (Poi p : newPois) {
      allPois.add(new PoiUpdateWrapper(true, p, null, null, PoiUpdateWrapper.PoiAction.CREATE));
    }
    for (Poi p : toDeletePois) {
      allPois.add(
          new PoiUpdateWrapper(
              true,
              p,
              poiDao.queryForId(p.getOldPoiId()),
              null,
              PoiUpdateWrapper.PoiAction.DELETED));
    }
    for (PoiNodeRef p : wayPoiNodeRef) {
      allPois.add(new PoiUpdateWrapper(false, null, null, p, PoiUpdateWrapper.PoiAction.UPDATE));
    }

    bus.post(new PoisToUpdateLoadedEvent(allPois));
  }
  /**
   * Get the backup data and put it back in the active NodeRefPoi
   *
   * @param poiNodeRefId The Id of the PoiNodeRef to revert.
   */
  private void revertPoiNodeRef(Long poiNodeRefId) {
    PoiNodeRef poiNodeRef = poiNodeRefDao.queryForId(poiNodeRefId);
    PoiNodeRef backup;
    Long oldId = poiNodeRef.getOldPoiId();

    if (oldId != null) {
      backup = poiNodeRefDao.queryForId(oldId);
      poiNodeRef.setLatitude(backup.getLatitude());
      poiNodeRef.setLongitude(backup.getLongitude());
      poiNodeRefDao.deleteById(oldId);
    }

    poiNodeRef.setUpdated(false);
    poiNodeRef.setOld(false);
    poiNodeRef.setOldPoiId(null);
    poiNodeRefDao.createOrUpdate(poiNodeRef);
  }
 public void onEventAsync(PleaseTellIfDbChanges event) {
   bus.post(
       new ChangesInDB(poiDao.countForAllChanges() > 0 || poiNodeRefDao.countAllToUpdate() > 0));
 }
 public void onEventAsync(PleaseLoadNodeRefAround event) {
   bus.post(
       new NodeRefAroundLoadedEvent(poiNodeRefDao.queryAllInRect(event.getLat(), event.getLng())));
 }