/**
   * Retrieve model from given result set.
   *
   * @param ctx
   * @param tableName
   * @param rs
   * @param trxName
   * @return loaded model; never return null
   */
  private final PO retrievePO(
      final Properties ctx, final String tableName, final ResultSet rs, final String trxName) {
    final Class<?> clazz = tableModelClassLoader.getClass(tableName);
    if (clazz == null) {
      log.info("Using GenericPO for {}", tableName);
      final GenericPO po = new GenericPO(tableName, ctx, rs, trxName);
      return po;
    }

    try {
      final Constructor<?> constructor = tableModelClassLoader.getResultSetConstructor(clazz);

      final PO po = (PO) constructor.newInstance(ctx, rs, trxName);
      return po;
    } catch (final Exception e) {
      throw new AdempiereException(
          "Error while loading model from ResultSet"
              + "\n@TableName@: "
              + tableName
              + "\nClass: "
              + clazz,
          e);
    }
  } // getPO
  /**
   * Loads the PO from database. In case some errors were encountered, they will be logged and
   * <code>null</code> will be returned.
   *
   * @param ctx
   * @param tableName
   * @param Record_ID
   * @param trxName
   * @return PO or null
   */
  private final PO retrievePO(
      final Properties ctx, final String tableName, int Record_ID, String trxName) {
    final POInfo poInfo = POInfo.getPOInfo(tableName);
    if (Record_ID > 0 && poInfo.getKeyColumnName() == null) {
      log.warn("(id) - Multi-Key " + tableName);
      return null;
    }

    final Class<?> clazz = tableModelClassLoader.getClass(tableName);
    if (clazz == null) {
      log.info("Using GenericPO for {}", tableName);
      final GenericPO po = new GenericPO(tableName, ctx, Record_ID, trxName);
      return po;
    }

    boolean errorLogged = false;
    try {
      final Constructor<?> constructor = tableModelClassLoader.getIDConstructor(clazz);
      final PO po = (PO) constructor.newInstance(ctx, Record_ID, trxName);
      if (po != null && po.get_ID() != Record_ID && Record_ID > 0) {
        return null;
      }
      return po;
    } catch (Exception e) {
      final Throwable cause = e.getCause() == null ? e : e.getCause();
      log.error("(id) - Table=" + tableName + ",Class=" + clazz, cause);
      MetasfreshLastError.saveError(log, "Error", cause);
      errorLogged = true;
    }

    if (!errorLogged) {
      log.error("(id) - Not found - Table=" + tableName + ", Record_ID=" + Record_ID);
    }

    return null;
  } // getPO