gt:             VDSGroup entity = new VDSGroup();
context: package org.ovirt.engine.core.dao;
  
  import java.sql.Array;
  import java.sql.Connection;
  import java.sql.ResultSet;
  import java.sql.SQLException;
  import java.util.HashMap;
  import java.util.LinkedHashMap;
  import java.util.List;
  import java.util.Map;
  
  import javax.inject.Named;
  import javax.inject.Singleton;
  
  import org.ovirt.engine.core.common.businessentities.ActionGroup;
  import org.ovirt.engine.core.common.businessentities.ArchitectureType;
  import org.ovirt.engine.core.common.businessentities.MigrateOnErrorOptions;
  import org.ovirt.engine.core.common.businessentities.SerialNumberPolicy;
  import org.ovirt.engine.core.common.businessentities.VDSGroup;
  import org.ovirt.engine.core.common.businessentities.VDSGroupHostsAndVMs;
  import org.ovirt.engine.core.common.businessentities.VmRngDevice;
  import org.ovirt.engine.core.common.scheduling.OptimizationType;
  import org.ovirt.engine.core.compat.Guid;
  import org.ovirt.engine.core.compat.Version;
  import org.ovirt.engine.core.dal.dbbroker.DbFacadeUtils;
  import org.ovirt.engine.core.utils.SerializationFactory;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.jdbc.core.RowMapper;
  import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
  
  /**
   * <code>VdsGroupDaoImpl</code> provides an implementation of {@link VdsGroupDao} that uses code previously
   * found in {@link org.ovirt.engine.core.dal.dbbroker.DbFacade}.
   *
   */
  @Named
  @Singleton
  public class VdsGroupDaoImpl extends BaseDao implements VdsGroupDao {
      private static final Logger log = LoggerFactory.getLogger(VdsGroupDaoImpl.class);
  
      @Override
      public VDSGroup get(Guid id) {
          return get(id, null, false);
      }
  
      @Override
      public VDSGroup get(Guid id, Guid userID, boolean isFiltered) {
          MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
                  .addValue("vds_group_id", id).addValue("user_id", userID).addValue("is_filtered", isFiltered);
  
          return getCallsHandler().executeRead("GetVdsGroupByVdsGroupId", VdsGroupRowMapper.instance, parameterSource);
      }
  
      @Override
      public VDSGroup getWithRunningVms(Guid id) {
          MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
                  .addValue("vds_group_id", id);
          return getCallsHandler().executeRead("GetVdsGroupWithRunningVms", VdsGroupRowMapper.instance, parameterSource);
      }
  
      @Override
      public Boolean getIsEmpty(Guid id) {
          MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
                  .addValue("vds_group_id", id);
          return getCallsHandler().executeRead("GetIsVdsGroupEmpty", BooleanRowMapper.instance, parameterSource);
      }
  
      @Override
      public VDSGroup getByName(String name) {
          return (VDSGroup) DbFacadeUtils.asSingleResult(getByName(name, true));
      }
  
      @Override
      public List<VDSGroup> getByName(String name, boolean isCaseSensitive) {
          MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
                  .addValue("vds_group_name", name)
                  .addValue("is_case_sensitive", isCaseSensitive);
  
          return getCallsHandler().executeReadList("GetVdsGroupByVdsGroupName",
                          VdsGroupRowMapper.instance,
                          parameterSource);
      }
  
      @Override
      public VDSGroup getByName(String name, Guid userID, boolean isFiltered) {
          MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
                  .addValue("vds_group_name", name).addValue("user_id", userID).addValue("is_filtered", isFiltered);
  
          return (VDSGroup) DbFacadeUtils.asSingleResult(
                  getCallsHandler().executeReadList("GetVdsGroupForUserByVdsGroupName",
                          VdsGroupRowMapper.instance,
                          parameterSource));
      }
  
      @Override
      public List<VDSGroup> getAllForStoragePool(Guid id) {
          return getAllForStoragePool(id, null, false);
      }
  
      @Override
      public List<VDSGroup> getAllForStoragePool(Guid id, Guid userID, boolean isFiltered) {
          MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
                  .addValue("storage_pool_id", id).addValue("user_id", userID).addValue("is_filtered", isFiltered);
  
          return getCallsHandler().executeReadList("GetVdsGroupsByStoragePoolId",
                  VdsGroupRowMapper.instance,
                  parameterSource);
      }
  
      @Override
      public List<VDSGroup> getAllWithQuery(String query) {
          List<VDSGroup> groups = getJdbcTemplate().query(query, VdsGroupRowMapper.instance);
  
          try {
              // The UI requires the host and vm count
              return getHostsAndVmsForClusters(groups);
          } catch (Exception e) {
              log.error("Can't load host and vm count for cluster. Query is '{}'. Error: {}", query, e.getMessage());
              log.debug("Excpetion", e);
          }
          return groups;
      }
  
      @Override
      public List<VDSGroup> getAll() {
          return getAll(null, false);
      }
  
      @Override
      public List<VDSGroup> getAll(Guid userID, boolean isFiltered) {
          MapSqlParameterSource parameterSource =
                  getCustomMapSqlParameterSource().addValue("user_id", userID).addValue("is_filtered", isFiltered);
          return getCallsHandler().executeReadList("GetAllFromVdsGroups", VdsGroupRowMapper.instance, parameterSource);
      }
  
      @Override
      public void save(VDSGroup group) {
          Guid id = group.getId();
          if (Guid.isNullOrEmpty(id)) {
              id = Guid.newGuid();
              group.setId(id);
          }
          getCallsHandler().executeModification("InsertVdsGroups", getVdsGroupParamSource(group));
      }
  
      @Override
      public void update(VDSGroup group) {
          getCallsHandler().executeModification("UpdateVdsGroup", getVdsGroupParamSource(group));
      }
  
      @Override
      public void remove(Guid id) {
          MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
                  .addValue("vds_group_id", id);
  
          getCallsHandler().executeModification("DeleteVdsGroup", parameterSource);
      }
  
      @Override
      public List<VDSGroup> getClustersWithPermittedAction(Guid userId, ActionGroup actionGroup) {
          MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
                  .addValue("user_id", userId).addValue("action_group_id", actionGroup.getId());
  
          return getCallsHandler().executeReadList("fn_perms_get_vds_groups_with_permitted_action",
                  VdsGroupRowMapper.instance,
                  parameterSource);
      }
  
      @Override
      public List<VDSGroup> getClustersHavingHosts() {
          MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource();
  
          return getCallsHandler().executeReadList("GetClustersHavingHosts",
                  VdsGroupRowMapper.instance,
                  parameterSource);
      }
  
      @Override
      public List<VDSGroup> getWithoutMigratingVms() {
          MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource();
  
          return getCallsHandler().executeReadList("GetVdsGroupsWithoutMigratingVms",
                  VdsGroupRowMapper.instance,
                  parameterSource);
      }
  
      @Override
      public void setEmulatedMachine(Guid vdsGroupId, String emulatedMachine, boolean detectEmulatedMachine) {
          MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
                  .addValue("vds_group_id", vdsGroupId)
                  .addValue("emulated_machine", emulatedMachine)
                  .addValue("detect_emulated_machine", detectEmulatedMachine);
  
          getCallsHandler().executeModification("UpdateVdsGroupEmulatedMachine", parameterSource);
      }
  
      @Override
      public int getVmsCountByClusterId(Guid vdsGroupId) {
          MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource().addValue("vds_group_id", vdsGroupId);
          return getCallsHandler().executeRead("GetNumberOfVmsInCluster",
                  getIntegerMapper(),
                  parameterSource);
      }
  
      @Override
      public List<VDSGroup> getTrustedClusters() {
          MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
                  .addValue("trusted_service", true);
          return getCallsHandler().executeReadList("GetTrustedVdsGroups", VdsGroupRowMapper.instance, parameterSource);
      }
  
      private MapSqlParameterSource getVdsGroupParamSource(VDSGroup group) {
          MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
                  .addValue("description", group.getDescription())
                  .addValue("name", group.getName())
                  .addValue("free_text_comment", group.getComment())
                  .addValue("vds_group_id", group.getId())
                  .addValue("cpu_name", group.getCpuName())
                  .addValue("storage_pool_id", group.getStoragePoolId())
                  .addValue("max_vds_memory_over_commit",
                          group.getMaxVdsMemoryOverCommit())
                  .addValue("count_threads_as_cores",
                          group.getCountThreadsAsCores())
                  .addValue("transparent_hugepages",
                          group.getTransparentHugepages())
                  .addValue("compatibility_version",
                          group.getCompatibilityVersion())
                  .addValue("migrate_on_error", group.getMigrateOnError())
                  .addValue("virt_service", group.supportsVirtService())
                  .addValue("gluster_service", group.supportsGlusterService())
                  .addValue("gluster_cli_based_snapshot_scheduled", group.isGlusterCliBasedSchedulingOn())
                  .addValue("tunnel_migration", group.isTunnelMigration())
                  .addValue("required_rng_sources", VmRngDevice.sourcesToCsv(group.getRequiredRngSources()))
                  .addValue("emulated_machine", group.getEmulatedMachine())
                  .addValue("detect_emulated_machine", group.isDetectEmulatedMachine())
                  .addValue("trusted_service", group.supportsTrustedService())
                  .addValue("ha_reservation", group.supportsHaReservation())
                  .addValue("optional_reason", group.isOptionalReasonRequired())
                  .addValue("maintenance_reason_required", group.isMaintenanceReasonRequired())
                  .addValue("cluster_policy_id", group.getClusterPolicyId())
                  .addValue("cluster_policy_custom_properties",
                                  SerializationFactory.getSerializer().serialize(group.getClusterPolicyProperties()))
                  .addValue("architecture", group.getArchitecture())
                  .addValue("enable_balloon", group.isEnableBallooning())
                  .addValue("optimization_type", group.getOptimizationType())
                  .addValue("enable_ksm", group.isEnableKsm())
                  .addValue("spice_proxy", group.getSpiceProxy())
                  .addValue("serial_number_policy", group.getSerialNumberPolicy() == null ? null : group.getSerialNumberPolicy().getValue())
                  .addValue("custom_serial_number", group.getCustomSerialNumber())
                  .addValue("skip_fencing_if_sd_active", group.getFencingPolicy().isSkipFencingIfSDActive())
                  .addValue("skip_fencing_if_connectivity_broken", group.getFencingPolicy().isSkipFencingIfConnectivityBroken())
                  .addValue("hosts_with_broken_connectivity_threshold", group.getFencingPolicy().getHostsWithBrokenConnectivityThreshold())
                  .addValue("fencing_enabled", group.getFencingPolicy().isFencingEnabled())
                  .addValue("is_auto_converge", group.getAutoConverge())
                  .addValue("is_migrate_compressed", group.getMigrateCompressed())
                  .addValue("gluster_tuned_profile", group.getGlusterTunedProfile())
                  .addValue("ksm_merge_across_nodes", group.isKsmMergeAcrossNumaNodes());
  
          return parameterSource;
      }
  
      private final static class VDSGroupHostsAndVMsRowMapper implements RowMapper<VDSGroupHostsAndVMs> {
          public static final RowMapper<VDSGroupHostsAndVMs> instance = new VDSGroupHostsAndVMsRowMapper();
  
          @Override
          public VDSGroupHostsAndVMs mapRow(ResultSet rs, int rowNum) throws SQLException {
              VDSGroupHostsAndVMs entity = new VDSGroupHostsAndVMs();
              entity.setHosts(rs.getInt("hosts"));
              entity.setVms(rs.getInt("vms"));
              entity.setVdsGroupId(getGuid(rs, "vds_group_id"));
              return entity;
          }
  
      }
      private final static class VdsGroupRowMapper implements RowMapper<VDSGroup> {
          public static final RowMapper<VDSGroup> instance = new VdsGroupRowMapper();
          @Override
          public VDSGroup mapRow(ResultSet rs, int rowNum)
                  throws SQLException {
  