@SuppressWarnings("unchecked")
 @Override
 public List<GeoObject> listByLayerIdWithTags(Long layerId) {
   List<GeoObject> objs =
       (List<GeoObject>)
           getCurrentSession()
               .createQuery(
                   ("Select o from GeoLayer l inner join l.geoObjects o left join fetch o.geoObjectProperties p left join fetch o.createdBy cb left join fetch o.changedBy chb where l.id = :layerId"))
               .setLong("layerId", layerId)
               .list();
   if (objs.size() == 0) return objs;
   List<GeoObjectTag> tags =
       getCurrentSession()
           .createQuery(
               "SELECT t from GeoObjectTag t join t.geoObject o join o.geoLayers l where l.id = :layerId")
           .setLong("layerId", layerId)
           .list();
   for (GeoObject obj : objs) {
     HashSet<GeoObjectTag> fetchedTags = new HashSet<GeoObjectTag>();
     for (GeoObjectTag tag : tags) {
       if (tag.getGeoObject().getId() == obj.getId()) {
         fetchedTags.add(tag);
       }
     }
     obj.setTags(fetchedTags);
   }
   return objs;
 }
 @Override
 @CacheEvict(value = "objectPermanent", allEntries = true)
 public void cloneObjectListToLayer(
     List<Long> objIdList, Long targetLayerId, GeoUser currentGeoUser) {
   List<GeoObject> originalObjects = listByIds(objIdList);
   for (GeoObject orig : originalObjects) {
     GeoObject obj = orig.clone();
     obj.setId(null);
     HashSet<GeoObjectTag> objectTags = new HashSet<GeoObjectTag>();
     for (GeoObjectTag prop : orig.getTags()) {
       GeoObjectTag tag = new GeoObjectTag();
       tag.setKey(prop.getKey());
       tag.setValue(prop.getValue());
       tag.setGeoObject(obj);
       objectTags.add(tag);
     }
     obj.setTags(objectTags);
     obj.setCreatedBy(currentGeoUser);
     obj.setCreated(Calendar.getInstance().getTime());
     getCurrentSession()
         .createSQLQuery(
             "INSERT INTO geo_layer_to_object (layer_id, object_id) VALUES(:lId, :oId)")
         .setLong("oId", add(obj).getId())
         .setLong("lId", targetLayerId)
         .executeUpdate();
   }
 }
  @RequestMapping(method = RequestMethod.GET)
  @ResponseBody
  public GetObjectsResponse list() {

    GeoUser user = serviceRegistry.getUserDao().getCurrentGeoUser();

    List<GeoObject> aclObjects = serviceRegistry.getACLDao().listByUser(user.getId());

    List<GeoObject> aclObjectsWithTags = new ArrayList<GeoObject>();
    for (GeoObject aclObject : aclObjects) {
      aclObjectsWithTags.add(serviceRegistry.getGeoObjectDao().getWithTags(aclObject.getId()));
    }

    GetObjectsResponse response = new GetObjectsResponse();
    response.setList(ObjectFactory.createGeoObjectFullAdapterList(aclObjectsWithTags));

    return response;
  }
  @Override
  public GeoObject getByRevision(Long id, Integer revId) {
    AuditQuery query =
        AuditReaderFactory.get(getCurrentSession())
            .createQuery()
            .forEntitiesAtRevision(GeoObject.class, revId);
    query.add(AuditEntity.id().eq(id));
    GeoObject object = (GeoObject) query.getSingleResult();

    AuditQuery queryTags =
        AuditReaderFactory.get(getCurrentSession())
            .createQuery()
            .forEntitiesAtRevision(GeoObjectTag.class, revId);
    // queryTags.add(AuditEntity.property("geoObject").eq(id));
    queryTags.add(AuditEntity.property("geoObject").eq(object));
    List tags = queryTags.getResultList();

    object.setTags(new HashSet<GeoObjectTag>(tags));
    return object;
  }
  @SuppressWarnings("unchecked")
  @Override
  public List<GeoObject> listByLayerIdFromRevision(Long layerId, Long revId) {
    List<GeoObject> objs =
        (List<GeoObject>)
            getCurrentSession()
                .createSQLQuery(getResourceSQL("GeoObjectDao.listByLayerIdFromRevision"))
                .addEntity(GeoObject.class)
                .setLong("layerId", layerId)
                .setLong("revId", revId)
                .list();
    if (objs.size() == 0) return objs;

    List<GeoObjectTag> tags =
        getCurrentSession()
            .createQuery("from GeoObjectTag t where t.geoObject in :objs")
            .setParameterList("objs", objs)
            .list();
    for (GeoObject obj : objs) {
      HashSet<GeoObjectTag> fetchedTags = new HashSet<GeoObjectTag>();
      for (GeoObjectTag tag : tags) {
        if (tag.getGeoObject().getId() == obj.getId()) {
          fetchedTags.add(tag);
        }
      }
      obj.setTags(fetchedTags);
    }
    return objs;

    /*
    for(GeoObject obj : objs){
    	 List<GeoObjectTag> tags = getCurrentSession().createQuery("from GeoObjectTag t where t.geoObject = :obj").setEntity("obj", obj).list();
    	 obj.setTags(new HashSet<GeoObjectTag>(tags));
    }
    return objs;
    */
  }
 @SuppressWarnings("unchecked")
 @Override
 public List<GeoObject> listByIdsNotManaged(List<Long> objIdList) {
   String sql = getResourceSQL("GeoObjectDao.listByIdsNotManaged");
   List<Object[]> rows =
       getCurrentSession()
           .createSQLQuery(sql.toString())
           .addScalar("id", StandardBasicTypes.LONG)
           .addScalar("name", StandardBasicTypes.STRING)
           .addScalar("created_by", StandardBasicTypes.LONG)
           .addScalar("changed_by", StandardBasicTypes.LONG)
           .addScalar("created", StandardBasicTypes.DATE)
           .addScalar("changed", StandardBasicTypes.DATE)
           .addScalar("fias_code", StandardBasicTypes.STRING)
           .addScalar("the_geom", GeometryUserType.TYPE)
           .addScalar("version", StandardBasicTypes.INTEGER)
           .setParameterList("ids", objIdList)
           .list();
   if (rows != null && rows.size() > 0) {
     GeoObject[] objects = new GeoObject[rows.size()];
     for (int j = 0; j < rows.size(); j++) {
       GeoObject obj = new GeoObject();
       Object[] row = rows.get(j);
       obj.setId((Long) row[0]);
       obj.setVersion((Integer) row[8]);
       Geometry geom = (Geometry) row[7];
       obj.setTheGeom(geom);
       obj.setName((String) row[1]);
       obj.setChanged((Date) row[5]);
       obj.setCreated((Date) row[4]);
       obj.setFiasCode((String) row[6]);
       objects[j] = obj;
     }
     return Arrays.asList(objects);
   }
   return new ArrayList<GeoObject>();
 }