@Override
  public void prepare(
      Collection<UnderReplicatedBlock> removed,
      Collection<UnderReplicatedBlock> newed,
      Collection<UnderReplicatedBlock> modified)
      throws StorageException {
    HopsSession session = connector.obtainSession();
    List<UnderReplicatedBlocksDTO> changes = new ArrayList<UnderReplicatedBlocksDTO>();
    List<UnderReplicatedBlocksDTO> deletions = new ArrayList<UnderReplicatedBlocksDTO>();
    for (UnderReplicatedBlock urBlock : removed) {
      UnderReplicatedBlocksDTO newInstance = session.newInstance(UnderReplicatedBlocksDTO.class);
      createPersistable(urBlock, newInstance);
      deletions.add(newInstance);
    }

    for (UnderReplicatedBlock urBlock : newed) {
      UnderReplicatedBlocksDTO newInstance = session.newInstance(UnderReplicatedBlocksDTO.class);
      createPersistable(urBlock, newInstance);
      changes.add(newInstance);
    }

    for (UnderReplicatedBlock urBlock : modified) {
      UnderReplicatedBlocksDTO newInstance = session.newInstance(UnderReplicatedBlocksDTO.class);
      createPersistable(urBlock, newInstance);
      changes.add(newInstance);
    }
    session.deletePersistentAll(deletions);
    session.savePersistentAll(changes);
  }
 @Override
 public void add(YarnRunningPrice yarnRunningPrice) throws StorageException {
   HopsSession session = connector.obtainSession();
   YarnRunningPriceClusterJ.YarnRunningPriceDTO toAdd =
       createPersistable(yarnRunningPrice, session);
   session.savePersistent(toAdd);
   session.release(toAdd);
 }
 @Override
 public void removeAll(Collection<SchedulerApplication> toRemove) throws StorageException {
   HopsSession session = connector.obtainSession();
   List<SchedulerApplicationDTO> toPersist = new ArrayList<SchedulerApplicationDTO>();
   for (SchedulerApplication entry : toRemove) {
     toPersist.add(session.newInstance(SchedulerApplicationDTO.class, entry.getAppid()));
   }
   session.deletePersistentAll(toPersist);
   session.release(toPersist);
 }
 @Override
 public List<UnderReplicatedBlock> findAll() throws StorageException {
   HopsSession session = connector.obtainSession();
   HopsQueryBuilder qb = session.getQueryBuilder();
   HopsQueryDomainType<UnderReplicatedBlocksDTO> dobj =
       qb.createQueryDefinition(UnderReplicatedBlocksDTO.class);
   HopsQuery<UnderReplicatedBlocksDTO> query = session.createQuery(dobj);
   query.setOrdering(Query.Ordering.ASCENDING, "level", "timestamp");
   List<UnderReplicatedBlock> blocks = createUrBlockList(query.getResultList());
   return blocks;
 }
 @Override
 public void addAll(Collection<SchedulerApplication> toAdd) throws StorageException {
   HopsSession session = connector.obtainSession();
   List<SchedulerApplicationDTO> toPersist = new ArrayList<SchedulerApplicationDTO>();
   for (SchedulerApplication req : toAdd) {
     toPersist.add(createPersistable(req, session));
   }
   session.savePersistentAll(toPersist);
   session.flush();
   session.release(toPersist);
 }
 @Override
 public Map<String, SchedulerApplication> getAll() throws StorageException {
   HopsSession session = connector.obtainSession();
   HopsQueryBuilder qb = session.getQueryBuilder();
   HopsQueryDomainType<SchedulerApplicationDTO> dobj =
       qb.createQueryDefinition(SchedulerApplicationClusterJ.SchedulerApplicationDTO.class);
   HopsQuery<SchedulerApplicationDTO> query = session.createQuery(dobj);
   List<SchedulerApplicationClusterJ.SchedulerApplicationDTO> queryResults = query.getResultList();
   Map<String, SchedulerApplication> result = createApplicationIdMap(queryResults);
   session.release(queryResults);
   return result;
 }
 @Override
 public List<UnderReplicatedBlock> findByINodeIds(int[] inodeIds) throws StorageException {
   HopsSession session = connector.obtainSession();
   HopsQueryBuilder qb = session.getQueryBuilder();
   HopsQueryDomainType<UnderReplicatedBlocksDTO> qdt =
       qb.createQueryDefinition(UnderReplicatedBlocksDTO.class);
   HopsPredicate pred1 = qdt.get("iNodeId").in(qdt.param("idParam"));
   qdt.where(pred1);
   HopsQuery<UnderReplicatedBlocksDTO> query = session.createQuery(qdt);
   query.setParameter("idParam", Ints.asList(inodeIds));
   return createUrBlockList(query.getResultList());
 }
  @Override
  public List<QuotaUpdate> findByInodeId(int inodeId) throws StorageException {
    HopsSession session = connector.obtainSession();
    HopsQueryBuilder qb = session.getQueryBuilder();
    HopsQueryDomainType<QuotaUpdateDTO> dobj = qb.createQueryDefinition(QuotaUpdateDTO.class);
    HopsPredicate pred1 = dobj.get("inodeId").equal(dobj.param(INODE_ID_PARAM));
    dobj.where(pred1);
    HopsQuery<QuotaUpdateDTO> query = session.createQuery(dobj);
    query.setParameter(INODE_ID_PARAM, inodeId);

    List<QuotaUpdateDTO> results = query.getResultList();
    return convertAndRelease(session, results);
  }
 @Override
 public List<UnderReplicatedBlock> findByLevel(int level) throws StorageException {
   HopsSession session = connector.obtainSession();
   HopsQueryBuilder qb = session.getQueryBuilder();
   HopsQueryDomainType<UnderReplicatedBlocksDTO> dobj =
       qb.createQueryDefinition(UnderReplicatedBlocksDTO.class);
   HopsPredicate pred = dobj.get("level").equal(dobj.param("level"));
   dobj.where(pred);
   HopsQuery<UnderReplicatedBlocksDTO> query = session.createQuery(dobj);
   query.setParameter("level", level);
   query.setOrdering(Query.Ordering.ASCENDING, "level", "timestamp");
   return createUrBlockList(query.getResultList());
 }
  @Override
  public UnderReplicatedBlock findByPk(long blockId, int inodeId) throws StorageException {
    HopsSession session = connector.obtainSession();
    Object[] pk = new Object[2];
    pk[0] = inodeId;
    pk[1] = blockId;

    UnderReplicatedBlocksDTO urbt = session.find(UnderReplicatedBlocksDTO.class, pk);
    if (urbt == null) {
      return null;
    }
    return createUrBlock(urbt);
  }
 @Override
 public List<UnderReplicatedBlock> findByINodeId(int inodeId) throws StorageException {
   HopsSession session = connector.obtainSession();
   HopsQueryBuilder qb = session.getQueryBuilder();
   HopsQueryDomainType<UnderReplicatedBlocksDTO> qdt =
       qb.createQueryDefinition(UnderReplicatedBlocksDTO.class);
   HopsPredicate pred1 = qdt.get("iNodeId").equal(qdt.param("idParam"));
   qdt.where(pred1);
   HopsQuery<UnderReplicatedBlocksDTO> query = session.createQuery(qdt);
   query.setParameter("idParam", inodeId);
   // FIXME[M]: it throws ClusterJUserException: There is no index containing the ordering fields.
   // http://bugs.mysql.com/bug.php?id=67765
   // query.setOrdering(HopsQuery.Ordering.ASCENDING, "level", "timestamp");
   return createUrBlockList(query.getResultList());
 }
  @Override
  public Map<YarnRunningPrice.PriceType, YarnRunningPrice> getAll() throws StorageException {
    LOG.debug("HOP :: ClusterJ YarnRunningPrice.getAll - START");
    HopsSession session = connector.obtainSession();
    HopsQueryBuilder qb = session.getQueryBuilder();

    HopsQueryDomainType<YarnRunningPriceClusterJ.YarnRunningPriceDTO> dobj =
        qb.createQueryDefinition(YarnRunningPriceClusterJ.YarnRunningPriceDTO.class);
    HopsQuery<YarnRunningPriceClusterJ.YarnRunningPriceDTO> query = session.createQuery(dobj);

    List<YarnRunningPriceClusterJ.YarnRunningPriceDTO> queryResults = query.getResultList();
    LOG.debug("HOP :: ClusterJ YarnRunningPrice.getAll - STOP");
    Map<YarnRunningPrice.PriceType, YarnRunningPrice> result = createMap(queryResults);
    session.release(queryResults);
    return result;
  }
  @Override
  public void prepare(Collection<QuotaUpdate> added, Collection<QuotaUpdate> removed)
      throws StorageException {
    HopsSession session = connector.obtainSession();
    List<QuotaUpdateDTO> changes = new ArrayList<QuotaUpdateDTO>();
    List<QuotaUpdateDTO> deletions = new ArrayList<QuotaUpdateDTO>();
    if (removed != null) {
      for (QuotaUpdate update : removed) {
        QuotaUpdateDTO persistable = createPersistable(update, session);
        deletions.add(persistable);
      }
    }
    if (added != null) {
      for (QuotaUpdate update : added) {
        QuotaUpdateDTO persistable = createPersistable(update, session);
        changes.add(persistable);
      }
    }
    session.deletePersistentAll(deletions);
    session.savePersistentAll(changes);

    session.release(deletions);
    session.release(changes);
  }
public class SchedulerApplicationClusterJ
    implements TablesDef.SchedulerApplicationTableDef,
        SchedulerApplicationDataAccess<SchedulerApplication> {

  @PersistenceCapable(table = TABLE_NAME)
  public interface SchedulerApplicationDTO {

    @PrimaryKey
    @Column(name = APPID)
    String getappid();

    void setappid(String appid);

    @Column(name = USER)
    String getuser();

    void setuser(String user);

    @Column(name = QUEUENAME)
    String getqueuename();

    void setqueuename(String queuename);
  }

  private final ClusterjConnector connector = ClusterjConnector.getInstance();

  @Override
  public Map<String, SchedulerApplication> getAll() throws StorageException {
    HopsSession session = connector.obtainSession();
    HopsQueryBuilder qb = session.getQueryBuilder();
    HopsQueryDomainType<SchedulerApplicationDTO> dobj =
        qb.createQueryDefinition(SchedulerApplicationClusterJ.SchedulerApplicationDTO.class);
    HopsQuery<SchedulerApplicationDTO> query = session.createQuery(dobj);
    List<SchedulerApplicationClusterJ.SchedulerApplicationDTO> queryResults = query.getResultList();
    Map<String, SchedulerApplication> result = createApplicationIdMap(queryResults);
    session.release(queryResults);
    return result;
  }

  @Override
  public void addAll(Collection<SchedulerApplication> toAdd) throws StorageException {
    HopsSession session = connector.obtainSession();
    List<SchedulerApplicationDTO> toPersist = new ArrayList<SchedulerApplicationDTO>();
    for (SchedulerApplication req : toAdd) {
      toPersist.add(createPersistable(req, session));
    }
    session.savePersistentAll(toPersist);
    session.flush();
    session.release(toPersist);
  }

  @Override
  public void removeAll(Collection<SchedulerApplication> toRemove) throws StorageException {
    HopsSession session = connector.obtainSession();
    List<SchedulerApplicationDTO> toPersist = new ArrayList<SchedulerApplicationDTO>();
    for (SchedulerApplication entry : toRemove) {
      toPersist.add(session.newInstance(SchedulerApplicationDTO.class, entry.getAppid()));
    }
    session.deletePersistentAll(toPersist);
    session.release(toPersist);
  }

  private Map<String, SchedulerApplication> createApplicationIdMap(
      List<SchedulerApplicationClusterJ.SchedulerApplicationDTO> list) {
    Map<String, SchedulerApplication> schedulerApplications =
        new HashMap<String, SchedulerApplication>();
    for (SchedulerApplicationClusterJ.SchedulerApplicationDTO persistable : list) {
      SchedulerApplication app = createHopSchedulerApplication(persistable);
      schedulerApplications.put(app.getAppid(), app);
    }
    return schedulerApplications;
  }

  private SchedulerApplication createHopSchedulerApplication(
      SchedulerApplicationDTO schedulerApplicationDTO) {
    return new SchedulerApplication(
        schedulerApplicationDTO.getappid(),
        schedulerApplicationDTO.getuser(),
        schedulerApplicationDTO.getqueuename());
  }

  private SchedulerApplicationDTO createPersistable(SchedulerApplication hop, HopsSession session)
      throws StorageException {
    SchedulerApplicationClusterJ.SchedulerApplicationDTO schedulerApplicationDTO =
        session.newInstance(SchedulerApplicationClusterJ.SchedulerApplicationDTO.class);

    schedulerApplicationDTO.setappid(hop.getAppid());
    schedulerApplicationDTO.setuser(hop.getUser());
    schedulerApplicationDTO.setqueuename(hop.getQueuename());
    return schedulerApplicationDTO;
  }
}
public class UnderReplicatedBlockClusterj
    implements TablesDef.UnderReplicatedBlockTableDef,
        UnderReplicatedBlockDataAccess<UnderReplicatedBlock> {

  @Override
  public int countByLevel(int level) throws StorageException {
    return MySQLQueryHelper.countWithCriterion(TABLE_NAME, String.format("%s=%d", LEVEL, level));
  }

  @Override
  public int countLessThanALevel(int level) throws StorageException {
    return MySQLQueryHelper.countWithCriterion(TABLE_NAME, String.format("%s<%d", LEVEL, level));
  }

  @PersistenceCapable(table = TABLE_NAME)
  @PartitionKey(column = INODE_ID)
  @Index(name = "level")
  public interface UnderReplicatedBlocksDTO {

    @PrimaryKey
    @Column(name = INODE_ID)
    int getINodeId();

    void setINodeId(int inodeId);

    @PrimaryKey
    @Column(name = BLOCK_ID)
    long getBlockId();

    void setBlockId(long bid);

    @Column(name = LEVEL)
    int getLevel();

    void setLevel(int level);

    @Column(name = TIMESTAMP)
    long getTimestamp();

    void setTimestamp(long timestamp);
  }

  private ClusterjConnector connector = ClusterjConnector.getInstance();

  @Override
  public UnderReplicatedBlock findByPk(long blockId, int inodeId) throws StorageException {
    HopsSession session = connector.obtainSession();
    Object[] pk = new Object[2];
    pk[0] = inodeId;
    pk[1] = blockId;

    UnderReplicatedBlocksDTO urbt = session.find(UnderReplicatedBlocksDTO.class, pk);
    if (urbt == null) {
      return null;
    }
    return createUrBlock(urbt);
  }

  @Override
  public void prepare(
      Collection<UnderReplicatedBlock> removed,
      Collection<UnderReplicatedBlock> newed,
      Collection<UnderReplicatedBlock> modified)
      throws StorageException {
    HopsSession session = connector.obtainSession();
    List<UnderReplicatedBlocksDTO> changes = new ArrayList<UnderReplicatedBlocksDTO>();
    List<UnderReplicatedBlocksDTO> deletions = new ArrayList<UnderReplicatedBlocksDTO>();
    for (UnderReplicatedBlock urBlock : removed) {
      UnderReplicatedBlocksDTO newInstance = session.newInstance(UnderReplicatedBlocksDTO.class);
      createPersistable(urBlock, newInstance);
      deletions.add(newInstance);
    }

    for (UnderReplicatedBlock urBlock : newed) {
      UnderReplicatedBlocksDTO newInstance = session.newInstance(UnderReplicatedBlocksDTO.class);
      createPersistable(urBlock, newInstance);
      changes.add(newInstance);
    }

    for (UnderReplicatedBlock urBlock : modified) {
      UnderReplicatedBlocksDTO newInstance = session.newInstance(UnderReplicatedBlocksDTO.class);
      createPersistable(urBlock, newInstance);
      changes.add(newInstance);
    }
    session.deletePersistentAll(deletions);
    session.savePersistentAll(changes);
  }

  private void createPersistable(UnderReplicatedBlock block, UnderReplicatedBlocksDTO persistable) {
    persistable.setBlockId(block.getBlockId());
    persistable.setLevel(block.getLevel());
    persistable.setINodeId(block.getInodeId());
    persistable.setTimestamp(System.currentTimeMillis());
  }

  private UnderReplicatedBlock createUrBlock(UnderReplicatedBlocksDTO bit) {
    UnderReplicatedBlock block =
        new UnderReplicatedBlock(bit.getLevel(), bit.getBlockId(), bit.getINodeId());
    return block;
  }

  private List<UnderReplicatedBlock> createUrBlockList(List<UnderReplicatedBlocksDTO> bitList) {
    List<UnderReplicatedBlock> blocks = new ArrayList<UnderReplicatedBlock>();
    for (UnderReplicatedBlocksDTO bit : bitList) {
      blocks.add(createUrBlock(bit));
    }
    return blocks;
  }

  @Override
  public int countAll() throws StorageException {
    return MySQLQueryHelper.countAll(TABLE_NAME);
  }

  @Override
  public List<UnderReplicatedBlock> findAll() throws StorageException {
    HopsSession session = connector.obtainSession();
    HopsQueryBuilder qb = session.getQueryBuilder();
    HopsQueryDomainType<UnderReplicatedBlocksDTO> dobj =
        qb.createQueryDefinition(UnderReplicatedBlocksDTO.class);
    HopsQuery<UnderReplicatedBlocksDTO> query = session.createQuery(dobj);
    query.setOrdering(Query.Ordering.ASCENDING, "level", "timestamp");
    List<UnderReplicatedBlock> blocks = createUrBlockList(query.getResultList());
    return blocks;
  }

  @Override
  public List<UnderReplicatedBlock> findByLevel(int level) throws StorageException {
    HopsSession session = connector.obtainSession();
    HopsQueryBuilder qb = session.getQueryBuilder();
    HopsQueryDomainType<UnderReplicatedBlocksDTO> dobj =
        qb.createQueryDefinition(UnderReplicatedBlocksDTO.class);
    HopsPredicate pred = dobj.get("level").equal(dobj.param("level"));
    dobj.where(pred);
    HopsQuery<UnderReplicatedBlocksDTO> query = session.createQuery(dobj);
    query.setParameter("level", level);
    query.setOrdering(Query.Ordering.ASCENDING, "level", "timestamp");
    return createUrBlockList(query.getResultList());
  }

  @Override
  public List<UnderReplicatedBlock> findByLevel(int level, int offset, int count)
      throws StorageException {
    HopsSession session = connector.obtainSession();
    HopsQueryBuilder qb = session.getQueryBuilder();
    HopsQueryDomainType<UnderReplicatedBlocksDTO> dobj =
        qb.createQueryDefinition(UnderReplicatedBlocksDTO.class);
    HopsPredicate pred = dobj.get("level").equal(dobj.param("level"));
    dobj.where(pred);
    HopsQuery<UnderReplicatedBlocksDTO> query = session.createQuery(dobj);
    query.setParameter("level", level);
    query.setOrdering(Query.Ordering.ASCENDING, "level", "timestamp");
    query.setLimits(offset, count);
    return createUrBlockList(query.getResultList());
  }

  @Override
  public List<UnderReplicatedBlock> findByINodeId(int inodeId) throws StorageException {
    HopsSession session = connector.obtainSession();
    HopsQueryBuilder qb = session.getQueryBuilder();
    HopsQueryDomainType<UnderReplicatedBlocksDTO> qdt =
        qb.createQueryDefinition(UnderReplicatedBlocksDTO.class);
    HopsPredicate pred1 = qdt.get("iNodeId").equal(qdt.param("idParam"));
    qdt.where(pred1);
    HopsQuery<UnderReplicatedBlocksDTO> query = session.createQuery(qdt);
    query.setParameter("idParam", inodeId);
    // FIXME[M]: it throws ClusterJUserException: There is no index containing the ordering fields.
    // http://bugs.mysql.com/bug.php?id=67765
    // query.setOrdering(HopsQuery.Ordering.ASCENDING, "level", "timestamp");
    return createUrBlockList(query.getResultList());
  }

  @Override
  public List<UnderReplicatedBlock> findByINodeIds(int[] inodeIds) throws StorageException {
    HopsSession session = connector.obtainSession();
    HopsQueryBuilder qb = session.getQueryBuilder();
    HopsQueryDomainType<UnderReplicatedBlocksDTO> qdt =
        qb.createQueryDefinition(UnderReplicatedBlocksDTO.class);
    HopsPredicate pred1 = qdt.get("iNodeId").in(qdt.param("idParam"));
    qdt.where(pred1);
    HopsQuery<UnderReplicatedBlocksDTO> query = session.createQuery(qdt);
    query.setParameter("idParam", Ints.asList(inodeIds));
    return createUrBlockList(query.getResultList());
  }

  @Override
  public void removeAll() throws StorageException {
    HopsSession session = connector.obtainSession();
    session.deletePersistentAll(UnderReplicatedBlocksDTO.class);
  }
}
public class YarnRunningPriceClusterJ
    implements YarnRunningPriceTableDef, YarnRunningPriceDataAccess<YarnRunningPrice> {

  private static final Log LOG = LogFactory.getLog(YarnRunningPriceClusterJ.class);

  @PersistenceCapable(table = TABLE_NAME)
  public interface YarnRunningPriceDTO {

    @PrimaryKey
    @Column(name = ID)
    String getId();

    void setId(String id);

    @Column(name = TIME)
    long getTime();

    void setTime(long time);

    @Column(name = PRICE)
    float getPrice();

    void setPrice(float price);
  }

  private final ClusterjConnector connector = ClusterjConnector.getInstance();

  @Override
  public Map<YarnRunningPrice.PriceType, YarnRunningPrice> getAll() throws StorageException {
    LOG.debug("HOP :: ClusterJ YarnRunningPrice.getAll - START");
    HopsSession session = connector.obtainSession();
    HopsQueryBuilder qb = session.getQueryBuilder();

    HopsQueryDomainType<YarnRunningPriceClusterJ.YarnRunningPriceDTO> dobj =
        qb.createQueryDefinition(YarnRunningPriceClusterJ.YarnRunningPriceDTO.class);
    HopsQuery<YarnRunningPriceClusterJ.YarnRunningPriceDTO> query = session.createQuery(dobj);

    List<YarnRunningPriceClusterJ.YarnRunningPriceDTO> queryResults = query.getResultList();
    LOG.debug("HOP :: ClusterJ YarnRunningPrice.getAll - STOP");
    Map<YarnRunningPrice.PriceType, YarnRunningPrice> result = createMap(queryResults);
    session.release(queryResults);
    return result;
  }

  public static Map<YarnRunningPrice.PriceType, YarnRunningPrice> createMap(
      List<YarnRunningPriceClusterJ.YarnRunningPriceDTO> results) {
    Map<YarnRunningPrice.PriceType, YarnRunningPrice> map =
        new HashMap<YarnRunningPrice.PriceType, YarnRunningPrice>();
    for (YarnRunningPriceClusterJ.YarnRunningPriceDTO persistable : results) {
      YarnRunningPrice hop = createHopYarnRunningPrice(persistable);
      map.put(hop.getId(), hop);
    }
    return map;
  }

  private static YarnRunningPrice createHopYarnRunningPrice(
      YarnRunningPriceClusterJ.YarnRunningPriceDTO csDTO) {
    YarnRunningPrice hop =
        new YarnRunningPrice(
            YarnRunningPrice.PriceType.valueOf(csDTO.getId()), csDTO.getTime(), csDTO.getPrice());
    return hop;
  }

  @Override
  public void add(YarnRunningPrice yarnRunningPrice) throws StorageException {
    HopsSession session = connector.obtainSession();
    YarnRunningPriceClusterJ.YarnRunningPriceDTO toAdd =
        createPersistable(yarnRunningPrice, session);
    session.savePersistent(toAdd);
    session.release(toAdd);
  }

  private YarnRunningPriceClusterJ.YarnRunningPriceDTO createPersistable(
      YarnRunningPrice hopPQ, HopsSession session) throws StorageException {
    YarnRunningPriceClusterJ.YarnRunningPriceDTO pqDTO =
        session.newInstance(YarnRunningPriceClusterJ.YarnRunningPriceDTO.class);
    // Set values to persist new YarnRunningPriceDTO
    pqDTO.setId(hopPQ.getId().name());
    pqDTO.setTime(hopPQ.getTime());
    pqDTO.setPrice(hopPQ.getPrice());

    return pqDTO;
  }
}
 @Override
 public void removeAll() throws StorageException {
   HopsSession session = connector.obtainSession();
   session.deletePersistentAll(UnderReplicatedBlocksDTO.class);
 }
public class QuotaUpdateClusterj
    implements TablesDef.QuotaUpdateTableDef, QuotaUpdateDataAccess<QuotaUpdate> {

  @PersistenceCapable(table = TABLE_NAME)
  public interface QuotaUpdateDTO {

    @PrimaryKey
    @Column(name = ID)
    int getId();

    void setId(int id);

    @PrimaryKey
    @Column(name = INODE_ID)
    int getInodeId();

    void setInodeId(int id);

    @Column(name = NAMESPACE_DELTA)
    long getNamespaceDelta();

    void setNamespaceDelta(long namespaceDelta);

    @Column(name = DISKSPACE_DELTA)
    long getDiskspaceDelta();

    void setDiskspaceDelta(long diskspaceDelta);
  }

  private ClusterjConnector connector = ClusterjConnector.getInstance();
  private MysqlServerConnector mysqlConnector = MysqlServerConnector.getInstance();

  @Override
  public void prepare(Collection<QuotaUpdate> added, Collection<QuotaUpdate> removed)
      throws StorageException {
    HopsSession session = connector.obtainSession();
    List<QuotaUpdateDTO> changes = new ArrayList<QuotaUpdateDTO>();
    List<QuotaUpdateDTO> deletions = new ArrayList<QuotaUpdateDTO>();
    if (removed != null) {
      for (QuotaUpdate update : removed) {
        QuotaUpdateDTO persistable = createPersistable(update, session);
        deletions.add(persistable);
      }
    }
    if (added != null) {
      for (QuotaUpdate update : added) {
        QuotaUpdateDTO persistable = createPersistable(update, session);
        changes.add(persistable);
      }
    }
    session.deletePersistentAll(deletions);
    session.savePersistentAll(changes);

    session.release(deletions);
    session.release(changes);
  }

  private static final String FIND_QUERY =
      "SELECT * FROM " + TABLE_NAME + " ORDER BY " + ID + " LIMIT ";

  @Override
  public List<QuotaUpdate> findLimited(int limit) throws StorageException {
    ArrayList<QuotaUpdate> resultList;
    try {
      Connection conn = mysqlConnector.obtainSession();
      PreparedStatement s = conn.prepareStatement(FIND_QUERY + limit);
      ResultSet result = s.executeQuery();
      resultList = new ArrayList<QuotaUpdate>();

      while (result.next()) {
        int id = result.getInt(ID);
        int inodeId = result.getInt(INODE_ID);
        int namespaceDelta = result.getInt(NAMESPACE_DELTA);
        long diskspaceDelta = result.getLong(DISKSPACE_DELTA);
        resultList.add(new QuotaUpdate(id, inodeId, namespaceDelta, diskspaceDelta));
      }
    } catch (SQLException ex) {
      throw HopsSQLExceptionHelper.wrap(ex);
    } finally {
      mysqlConnector.closeSession();
    }
    return resultList;
  }

  private QuotaUpdateDTO createPersistable(QuotaUpdate update, HopsSession session)
      throws StorageException {
    QuotaUpdateDTO dto = session.newInstance(QuotaUpdateDTO.class);
    dto.setId(update.getId());
    dto.setInodeId(update.getInodeId());
    dto.setNamespaceDelta(update.getNamespaceDelta());
    dto.setDiskspaceDelta(update.getDiskspaceDelta());
    return dto;
  }

  private List<QuotaUpdate> convertAndRelease(HopsSession session, List<QuotaUpdateDTO> list)
      throws StorageException {
    List<QuotaUpdate> result = new ArrayList<QuotaUpdate>();
    for (QuotaUpdateDTO dto : list) {
      result.add(
          new QuotaUpdate(
              dto.getId(), dto.getInodeId(), dto.getNamespaceDelta(), dto.getDiskspaceDelta()));
      session.release(dto);
    }
    return result;
  }

  private static final String INODE_ID_PARAM = "inodeId";

  @Override
  public List<QuotaUpdate> findByInodeId(int inodeId) throws StorageException {
    HopsSession session = connector.obtainSession();
    HopsQueryBuilder qb = session.getQueryBuilder();
    HopsQueryDomainType<QuotaUpdateDTO> dobj = qb.createQueryDefinition(QuotaUpdateDTO.class);
    HopsPredicate pred1 = dobj.get("inodeId").equal(dobj.param(INODE_ID_PARAM));
    dobj.where(pred1);
    HopsQuery<QuotaUpdateDTO> query = session.createQuery(dobj);
    query.setParameter(INODE_ID_PARAM, inodeId);

    List<QuotaUpdateDTO> results = query.getResultList();
    return convertAndRelease(session, results);
  }
}