code: public <T, I> T getObject(Keyspace keyspace, String colFamName, I pkObj) {
      if (null == pkObj) {
        throw new IllegalArgumentException("object ID cannot be null or empty");
      }
  
      CFMappingDef<T> cfMapDef = cacheMgr.getCfMapDef(colFamName, true);
  
      byte[] colFamKey = generateColumnFamilyKeyFromPkObj(cfMapDef, pkObj);
  
      SliceQuery<byte[], String, byte[]> q = HFactory.createSliceQuery(keyspace,
          BytesArraySerializer.get(), StringSerializer.get(), BytesArraySerializer.get());
      q.setColumnFamily(colFamName);
      q.setKey(colFamKey);
  
      // if no anonymous handler then use specific columns
      if (cfMapDef.isColumnSliceRequired()) {
        q.setColumnNames(cfMapDef.getSliceColumnNameArr());
      } else {
        q.setRange("", "", false, maxNumColumns);
      }
  
      QueryResult<ColumnSlice<String, byte[]>> result = q.execute();
      if (null == result || null == result.get()) {
        return null;
      }
  
      T obj = createObject(cfMapDef, pkObj, result.get());
      return obj;
    }
docs: Retrieve columns from cassandra keyspace and column family, instantiate a
  new object of required type, and then map them to the object's properties.
  
  @param <T>
  
  @param keyspace
  @param colFamName
  @param pkObj
  @return