Find.

@param clazz
the clazz
@param metadata
the metadata
@param rowId
the row id
@param relationNames
the relation names
@return the object
434355
private final Object find(Class<?> clazz, EntityMetadata metadata, Object rowId, List<String> relationNames) {

        List<Object> result = null;
        try {
            MetamodelImpl metaModel =
                (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(metadata.getPersistenceUnit());

            EntityType entityType = metaModel.entity(clazz);

            List<ManagedType> subTypes = ((AbstractManagedType) entityType).getSubManagedType();

            if (!subTypes.isEmpty()) {
                for (ManagedType subEntity : subTypes) {
                    EntityMetadata subEntityMetadata =
                        KunderaMetadataManager.getEntityMetadata(kunderaMetadata, subEntity.getJavaType());
                    result = populate(clazz, subEntityMetadata, rowId, subEntityMetadata.getRelationNames(), metaModel);
                    if (result != null && !result.isEmpty()) {
                        break;
                    }
                }
            } else {
                result = populate(clazz, metadata, rowId, relationNames, metaModel);
            }
        } catch (Exception e) {
            log.error("Error while retrieving records from database for entity {} and key {}, Caused by: .", clazz,
                rowId, e);

            throw new PersistenceException(e);
        }

        return result != null && !result.isEmpty() ? result.get(0) : null;
    }
758342
private <X> void populateRelationMetaData(EntityType entityType, Class<X> clazz, EntityMetadata metadata)
    {
        Set<Attribute> attributes = entityType.getAttributes();

        for (Attribute attribute : attributes)
        {
            if (attribute.isAssociation())
            {

                addRelationIntoMetadata(clazz, (Field) attribute.getJavaMember(), metadata);
            }
        }

    }
615689
@Override
    public final <E> List<E> findAll(Class<E> entityClass, String[] columnsToSelect, Object... rowIds)
    {
        return super.findAll(entityClass, columnsToSelect, rowIds);
    }
222026
private void parseRelations(final Object originalEntity, final Object relationEntity,
            final Map<String, Object> relationsMap, final PersistenceDelegator pd, final EntityMetadata metadata,
            boolean lazilyloaded, Map<Object, Object> relationStack)
    {

        for (Relation relation : metadata.getRelations())
        {
            if (relation != null)
            {
                FetchType fetchType = relation.getFetchType();

                if (!lazilyloaded && fetchType.equals(FetchType.LAZY))
                {
                    final Object entityId = PropertyAccessorHelper.getId(relationEntity, metadata);
                    getAssociationBuilder().setProxyRelationObject(relationEntity, relationsMap, metadata, pd,
                            entityId, relation);
                }
                else
                {

                    if (relation.isUnary() && relation.getTargetEntity().isAssignableFrom(originalEntity.getClass()))
                    {
                        Object associationObject = PropertyAccessorHelper.getObject(relationEntity,
                                relation.getProperty());
                        if (relation.getType().equals(ForeignKey.ONE_TO_ONE))
                        {
                            if ((associationObject == null || ProxyHelper.isProxyOrCollection(associationObject)))
                            {
                                PropertyAccessorHelper.set(relationEntity, relation.getProperty(), originalEntity);
                            }
                        }
                        else if (relationsMap != null
                                && relationsMap.containsKey(relation.getJoinColumnName(kunderaMetadata)))
                        {
                            PropertyAccessorHelper.set(relationEntity, relation.getProperty(), originalEntity);
                        }
                    }
                    else
                    {
                        // Here
                        // onRelation(relationEntity, relationsMap, metadata,
                        // pd,
                        // relation, relationType);
                        final Object entityId = PropertyAccessorHelper.getId(relationEntity, metadata);
                        Object relationValue = relationsMap != null ? relationsMap.get(relation
                                .getJoinColumnName(kunderaMetadata)) : null;
                        final EntityMetadata targetEntityMetadata = KunderaMetadataManager.getEntityMetadata(
                                kunderaMetadata, relation.getTargetEntity());
                        List immediateRelations = fetchRelations(relation, metadata, pd, entityId, relationValue,
                                targetEntityMetadata);
                        // Here in case of one-to-many/many-to-one we should
                        // skip
                        // this
                        // relation as it
                        if (immediateRelations != null && !immediateRelations.isEmpty())
                        {
                            for (Object immediateRelation : immediateRelations)
                            {
                                if (immediateRelation != null )
                                {
                                    if (existsInRelationStack(relationStack, immediateRelation, targetEntityMetadata))
                                    {
                                        setRelationToEntity(
                                                relationEntity,
                                                fetchFromRelationStack(relationStack, immediateRelation,
                                                        targetEntityMetadata), relation);

                                    }
                                    else
                                    {
                                        addToRelationStack(relationStack, immediateRelation, targetEntityMetadata);
                                        onParseRelation(relationEntity, pd, targetEntityMetadata, immediateRelation,
                                                relation, lazilyloaded, relationStack);
                                      

                                    }
                                    PersistenceCacheManager.addEntityToPersistenceCache(getEntity(relationEntity), pd,
                                            PropertyAccessorHelper.getId(relationEntity, metadata));
                                }
                            }

                        }
                    }
                }
            }
        }
    }
1312462
@Override
    public List<Object> findByRelation(String colName, Object colValue, Class entityClazz)
    {
        // find by relational value !

        EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(kunderaMetadata, entityClazz);
        MetamodelImpl metamodel = (MetamodelImpl) KunderaMetadataManager.getMetamodel(kunderaMetadata,
                entityMetadata.getPersistenceUnit());

        EntityType entityType = metamodel.entity(entityMetadata.getEntityClazz());

        Table schemaTable = tableAPI.getTable(entityMetadata.getTableName());

        Iterator<Row> rowsIter = null;
        if (schemaTable.getPrimaryKey().contains(colName))
        {
            PrimaryKey rowKey = schemaTable.createPrimaryKey();
            NoSqlDBUtils.add(schemaTable.getField(colName), rowKey, colValue, colName);
            rowsIter = tableAPI.tableIterator(rowKey, null, null);
        }
        else
        {
            Index index = schemaTable.getIndex(colName);
            IndexKey indexKey = index.createIndexKey();
            NoSqlDBUtils.add(schemaTable.getField(colName), indexKey, colValue, colName);
            rowsIter = tableAPI.tableIterator(indexKey, null, null);
        }

        try
        {
            Map<String, Object> relationMap = initialize(entityMetadata);

            return scrollAndPopulate(null, entityMetadata, metamodel, schemaTable, rowsIter, relationMap, null);
        }
        catch (Exception e)
        {
            log.error("Error while finding data for Key " + colName + ", Caused By :" + e + ".");
            throw new PersistenceException(e);
        }

    }
329976
@Override
    public List readAll(final String tableName, Class clazz, EntityMetadata m, final List<Object> rowKey,
            List<String> relationNames, String... columns) throws IOException
    {
        Table hTable = gethTable(tableName);
        List<HBaseDataWrapper> results = ((HBaseReader) hbaseReader).loadAll(hTable, rowKey, null, columns);
        return onRead(m, null, hTable, results);
    }
1305819
private Object find(Class entityClass, Object key, List<String> columnsToSelect)
    {
        EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(kunderaMetadata, entityClass);
        MetamodelImpl metamodel = (MetamodelImpl) KunderaMetadataManager.getMetamodel(kunderaMetadata,
                entityMetadata.getPersistenceUnit());

        String idColumnName = ((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName();
        Table schemaTable = tableAPI.getTable(entityMetadata.getTableName());

        PrimaryKey rowKey = schemaTable.createPrimaryKey();
        if (metamodel.isEmbeddable(entityMetadata.getIdAttribute().getBindableJavaType()))
        {
            readEmbeddable(key, columnsToSelect, entityMetadata, metamodel, schemaTable, rowKey,
                    entityMetadata.getIdAttribute());
        }
        else
        {
            if (eligibleToFetch(columnsToSelect, idColumnName))
            {
                NoSqlDBUtils.add(schemaTable.getField(idColumnName), rowKey, key, idColumnName);
            }
        }
        KunderaCoreUtils.printQuery("Fetch data from " + entityMetadata.getTableName() + " for PK " + key, showQuery);
        if (log.isDebugEnabled())
        {
            log.debug("Fetching data from " + entityMetadata.getTableName() + " for PK " + key);
        }

        // Object entity = null;
        List entities = new ArrayList();
        Map<String, Object> relationMap = initialize(entityMetadata);

        try
        {
            Iterator<Row> rowsIter = tableAPI.tableIterator(rowKey, null, null);
            // iterator and build entity
            entities = scrollAndPopulate(key, entityMetadata, metamodel, schemaTable, rowsIter, relationMap,
                    columnsToSelect);
        }
        catch (Exception e)
        {
            log.error("Error while finding data for Key " + key + ", Caused By :" + e + ".");
            throw new PersistenceException(e);
        }

        return entities.isEmpty() ? null : entities.get(0);
    }
71764
public List find(String nativeQuery, List<String> relations, EntityMetadata m)
    {
        List entities = new ArrayList();

        s = getStatelessSession();

        SQLQuery q = s.createSQLQuery(nativeQuery);
        q.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE);

        List result = q.list();

        try
        {
            MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(
                    m.getPersistenceUnit());

            EntityType entityType = metaModel.entity(m.getEntityClazz());

            List<AbstractManagedType> subManagedType = ((AbstractManagedType) entityType).getSubManagedType();
            for (Object o : result)
            {
                Map<String, Object> relationValue = null;
                Object entity = null;
                EntityMetadata subEntityMetadata = null;
                if (!subManagedType.isEmpty())
                {
                    for (AbstractManagedType subEntity : subManagedType)
                    {
                        String discColumn = subEntity.getDiscriminatorColumn();
                        String disColValue = subEntity.getDiscriminatorValue();
                        Object value = ((Map<String, Object>) o).get(discColumn);
                        if (value != null && value.toString().equals(disColValue))
                        {
                            subEntityMetadata = KunderaMetadataManager.getEntityMetadata(kunderaMetadata,
                                    subEntity.getJavaType());
                            break;
                        }
                    }
                    entity = instantiateEntity(subEntityMetadata.getEntityClazz(), entity);
                    relationValue = HibernateUtils.getTranslatedObject(kunderaMetadata, entity,
                            (Map<String, Object>) o, m);

                }
                else
                {
                    entity = instantiateEntity(m.getEntityClazz(), entity);
                    relationValue = HibernateUtils.getTranslatedObject(kunderaMetadata, entity,
                            (Map<String, Object>) o, m);
                }

                if (relationValue != null && !relationValue.isEmpty())
                {
                    entity = new EnhanceEntity(entity, PropertyAccessorHelper.getId(entity, m), relationValue);
                }
                entities.add(entity);
            }
            return entities;
        }
        catch (Exception e)
        {
            if (e.getMessage().equals("Can not be translated into entity."))
            {
                return result;
            }
            throw new EntityReaderException(e);
        }
    }
817721
@Override
    public List find(List<IndexClause> ixClause, EntityMetadata m, boolean isRelation, List<String> relations,
            int maxResult, List<String> columns)
    {
        List<Object> entities = new ArrayList<Object>();
        Connection conn = null;
        try
        {
            // ixClause can be 0,1 or more!
            SlicePredicate slicePredicate = new SlicePredicate();

            if (columns != null && !columns.isEmpty())
            {
                List asList = new ArrayList(32);
                for (String colName : columns)
                {
                    if (colName != null)
                    {
                        asList.add(UTF8Type.instance.decompose(colName));
                    }
                }
                slicePredicate.setColumn_names(asList);
            }
            else
            {
                SliceRange sliceRange = new SliceRange();
                sliceRange.setStart(ByteBufferUtil.EMPTY_BYTE_BUFFER);
                sliceRange.setFinish(ByteBufferUtil.EMPTY_BYTE_BUFFER);
                slicePredicate.setSlice_range(sliceRange);
            }
            conn = getConnection();

            if (ixClause.isEmpty())
            {
                KeyRange keyRange = new KeyRange(maxResult);
                keyRange.setStart_key(ByteBufferUtil.EMPTY_BYTE_BUFFER);
                keyRange.setEnd_key(ByteBufferUtil.EMPTY_BYTE_BUFFER);

                if (m.isCounterColumnType())
                {
                    List<KeySlice> ks = conn.getClient().get_range_slices(new ColumnParent(m.getTableName()),
                            slicePredicate, keyRange, getConsistencyLevel());
                    entities = onCounterColumn(m, isRelation, relations, ks);

                }
                else
                {
                    List<KeySlice> keySlices = conn.getClient().get_range_slices(new ColumnParent(m.getTableName()),
                            slicePredicate, keyRange, getConsistencyLevel());

                    if (m.getType().isSuperColumnFamilyMetadata())
                    {
                        Map<ByteBuffer, List<SuperColumn>> qResults = ThriftDataResultHelper.transformThriftResult(
                                ColumnFamilyType.SUPER_COLUMN, keySlices, null);
                        entities = new ArrayList<Object>(qResults.size());
                        computeEntityViaSuperColumns(m, isRelation, relations, entities, qResults);
                    }
                    else
                    {
                        Map<ByteBuffer, List<Column>> qResults = ThriftDataResultHelper.transformThriftResult(
                                ColumnFamilyType.COLUMN, keySlices, null);
                        entities = new ArrayList<Object>(qResults.size());
                        computeEntityViaColumns(m, isRelation, relations, entities, qResults);
                    }
                }
            }
            else
            {
                entities = new ArrayList<Object>();
                for (IndexClause ix : ixClause)
                {
                    List<KeySlice> keySlices = conn.getClient().get_indexed_slices(new ColumnParent(m.getTableName()),
                            ix, slicePredicate, getConsistencyLevel());

                    Map<ByteBuffer, List<Column>> qResults = ThriftDataResultHelper.transformThriftResult(
                            ColumnFamilyType.COLUMN, keySlices, null);
                    // iterate through complete map and populate.
                    entities = new ArrayList<Object>(qResults.size());

                    computeEntityViaColumns(m, isRelation, relations, entities, qResults);
                }
            }
        }
        catch (InvalidRequestException irex)
        {
            log.error("Error during executing find of column family {}, Caused by: .", m.getTableName(), irex);
            throw new PersistenceException(irex);
        }
        catch (UnavailableException uex)
        {
            log.error("Error during executing find of column family {}, Caused by: .", m.getTableName(), uex);
            throw new PersistenceException(uex);
        }
        catch (TimedOutException tex)
        {
            log.error("Error during executing find of column family {}, Caused by: .", m.getTableName(), tex);
            throw new PersistenceException(tex);
        }
        catch (TException tex)
        {
            log.error("Error during executing find of column family {}, Caused by: .", m.getTableName(), tex);
            throw new PersistenceException(tex);
        }
        finally
        {

            releaseConnection(conn);
        }
        return entities;
    }
398348
public Map<String, Object> getEntityFromDocument(Class<?> entityClass, Object entity, EntityMetadata m,
            DBObject document, List<String> relations, Map<String, Object> relationValue,
            final KunderaMetadata kunderaMetadata)
    {
        // Map to hold property-name=>foreign-entity relations
        try
        {
            // Populate primary key column
            Object rowKey = document.get("_id");
            Class<?> rowKeyValueClass = rowKey.getClass();
            Class<?> idClass = null;
            MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata()
                    .getMetamodel(m.getPersistenceUnit());
            idClass = m.getIdAttribute().getJavaType();
            rowKey = MongoDBUtils.populateValue(rowKey, idClass);
            AbstractAttribute idAttrib = (AbstractAttribute) m.getIdAttribute();
            if (metaModel.isEmbeddable(idAttrib.getBindableJavaType()))
            {
                populateEntityFromDocument(entity, rowKey, metaModel, idAttrib);
            }
            else
            {
                rowKey = MongoDBUtils.getTranslatedObject(rowKey, rowKeyValueClass, idClass);
                PropertyAccessorHelper.setId(entity, m, rowKey);
            }

            // Populate entity columns
            EntityType entityType = metaModel.entity(entityClass);

            Set<Attribute> columns = entityType.getAttributes();

            for (Attribute column : columns)
            {
                if (!column.equals(m.getIdAttribute()))
                {
                    String jpaColumnName = ((AbstractAttribute) column).getJPAColumnName();

                    Class javaType = ((AbstractAttribute) column).getBindableJavaType();
                    if (metaModel.isEmbeddable(javaType))
                    {
                        onViaEmbeddable(column, entity, metaModel, document);
                    }
                    else if (!column.isAssociation())
                    {
                        DocumentObjectMapper.setFieldValue(document, entity, column, false);
                    }
                    else if (relations != null)
                    {
                        if (relationValue == null)
                        {
                            relationValue = new HashMap<>();
                        }

                        if (relations.contains(jpaColumnName)
                                && !jpaColumnName.equals(((AbstractAttribute) m.getIdAttribute()).getJPAColumnName()))
                        {
                            Object colValue = document.get(jpaColumnName);
                            if (colValue != null)
                            {
                                String colFieldName = m.getFieldName(jpaColumnName);

                                EntityMetadata relationMetadata = KunderaMetadataManager.getEntityMetadata(
                                        kunderaMetadata, ((AbstractAttribute) entityType.getAttribute(colFieldName))
                                                .getBindableJavaType());

                                colValue = MongoDBUtils.getTranslatedObject(colValue, colValue.getClass(),
                                        relationMetadata.getIdAttribute().getJavaType());

                            }
                            relationValue.put(jpaColumnName, colValue);
                        }
                    }
                }
            }
            return relationValue;
        }
        catch (InstantiationException e)
        {
            log.error("Error while instantiating " + entityClass + ", Caused by: ", e);
            return relationValue;
        }
        catch (IllegalAccessException e)
        {
            log.error("Error while Getting entity from Document, Caused by: ", e);
            return relationValue;
        }
        catch (PropertyAccessException e)
        {
            log.error("Error while Getting entity from Document, Caused by: ", e);
            return relationValue;
        }
    }
966608
public final List findByRowKeys(Class entityClass, List<String> relationNames, boolean isWrapReq,
        EntityMetadata metadata, Object... rowIds) {
        List entities = null;

        MetamodelImpl metaModel =
            (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(metadata.getPersistenceUnit());

        EntityType entityType = metaModel.entity(metadata.getEntityClazz());

        List<AbstractManagedType> subManagedType = ((AbstractManagedType) entityType).getSubManagedType();

        try {
            if (!subManagedType.isEmpty()) {
                for (AbstractManagedType subEntity : subManagedType) {
                    EntityMetadata subEntityMetadata =
                        KunderaMetadataManager.getEntityMetadata(kunderaMetadata, subEntity.getJavaType());
                    entities = getDataHandler().fromThriftRow(entityClass, subEntityMetadata,
                        subEntityMetadata.getRelationNames(), isWrapReq, getConsistencyLevel(), rowIds);

                    if (entities != null && !entities.isEmpty()) {
                        break;
                    }
                }
            } else {
                entities = getDataHandler().fromThriftRow(entityClass, metadata, relationNames, isWrapReq,
                    getConsistencyLevel(), rowIds);
            }
        } catch (Exception e) {
            log.error("Error while retrieving records for entity {}, row keys {}", entityClass, rowIds);
            throw new KunderaException(e);
        }
        return entities;
    }
620603
@Override
    public Object find(Class entityClass, Object rowId)
    {
        EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(kunderaMetadata, entityClass);
        List<String> relationNames = entityMetadata.getRelationNames();
        // columnFamily has a different meaning for HBase, so it won't be used
        // here
        String tableName = entityMetadata.getSchema();
        Object enhancedEntity = null;
        List results = null;
        try
        {
            if (rowId == null)
            {
                return null;
            }

            MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(
                    entityMetadata.getPersistenceUnit());

            if (metaModel.isEmbeddable(entityMetadata.getIdAttribute().getBindableJavaType()))
            {
                rowId = KunderaCoreUtils.prepareCompositeKey(entityMetadata, rowId);
            }

            results = fetchEntity(entityClass, rowId, entityMetadata, relationNames, tableName, results, null, null);

            if (results != null && !results.isEmpty())
            {
                enhancedEntity = results.get(0);
            }
        }
        catch (IOException e)
        {
            log.error("Error during find by id, Caused by: .", e);
            throw new KunderaException(e);
        }
        return enhancedEntity;
    }
618113
@Override
    public List<Object> findByRelation(String colName, Object colValue, Class entityClazz)
    {
        return null;
    }
562974
@Override
    public List readData(final String tableName, Class clazz, EntityMetadata m, final Object rowKey,
            List<String> relationNames, FilterList f, String... columns) throws IOException
    {

        List output = null;

        Object entity = null;

        HTableInterface hTable = null;

        hTable = gethTable(tableName);

        if (getFilter(m.getTableName()) != null)
        {
            if (f == null)
            {
                f = new FilterList();
            }
            f.addFilter(getFilter(m.getTableName()));
        }

        // Load raw data from HBase
        MetamodelImpl metaModel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(
                m.getPersistenceUnit());

        AbstractManagedType managedType = (AbstractManagedType) metaModel.entity(m.getEntityClazz());
        // For secondary tables.
        List<String> secondaryTables = ((DefaultEntityAnnotationProcessor) managedType.getEntityAnnotation())
                .getSecondaryTablesName();
        secondaryTables.add(m.getTableName());
        Collections.shuffle(secondaryTables);
        List<HBaseData> results = new ArrayList<HBaseData>();
        for (String colTableName : secondaryTables)
        {
            results.addAll(hbaseReader.LoadData(hTable, colTableName, rowKey, f, columns));
        }

        output = onRead(tableName, clazz, m, output, hTable, entity, relationNames, results);
        return output;
    }
1288429
public static Field findField(Class<?> clazz, String name) {
        Class<?> entityClass = clazz;
        while (!Object.class.equals(entityClass) && entityClass != null) {
            Field[] fields = entityClass.getDeclaredFields();
            for (Field field : fields) {
                if (name.equals(field.getName())) {
                    return field;
                }
            }
            entityClass = entityClass.getSuperclass();
        }
        return null;
    }
556467
public List<Object> findByRelation(String colName, Object colValue, Class entityClazz)
    {
        EntityMetadata m = KunderaMetadataManager.getEntityMetadata(kunderaMetadata, entityClazz);
        // you got column name and column value.
        DBCollection dbCollection = mongoDb.getCollection(m.getTableName());

        BasicDBObject query = new BasicDBObject();

        query.put(colName, MongoDBUtils.populateValue(colValue, colValue.getClass()));
        KunderaCoreUtils.printQuery("Find by relation:" + query, showQuery);
        DBCursor cursor = dbCollection.find(query);
        DBObject fetchedDocument = null;
        List<Object> results = new ArrayList<Object>();
        while (cursor.hasNext())
        {
            fetchedDocument = cursor.next();
            populateEntity(m, results, fetchedDocument);
        }

        return results.isEmpty() ? null : results;
    }
215884
private Object find(Class entityClass, Object key, EntityMetadata entityMetadata, MetamodelImpl metaModel,
            AbstractManagedType managedType)
    {
        List<String> relationNames = entityMetadata.getRelationNames();

        BasicDBObject query = new BasicDBObject();

        if (metaModel.isEmbeddable(entityMetadata.getIdAttribute().getBindableJavaType()))
        {
            MongoDBUtils.populateCompoundKey(query, entityMetadata, metaModel, key);
        }
        else
        {
            query.put("_id", MongoDBUtils.populateValue(key, key.getClass()));
        }

        // For secondary tables.
        List<String> secondaryTables = ((DefaultEntityAnnotationProcessor) managedType.getEntityAnnotation())
                .getSecondaryTablesName();
        secondaryTables.add(entityMetadata.getTableName());

        Object enhancedEntity = null;
        Map<String, Object> relationValue = null;
        // Here you need to fetch by sub managed type.

        EntityType entityType = metaModel.entity(entityMetadata.getEntityClazz());

        for (String tableName : secondaryTables)
        {
            DBCollection dbCollection = mongoDb.getCollection(tableName);
            KunderaCoreUtils.printQuery("Find document:" + query, showQuery);
            DBObject fetchedDocument = dbCollection.findOne(query);

            if (fetchedDocument != null)
            {
                List<AbstractManagedType> subManagedType = ((AbstractManagedType) entityType).getSubManagedType();

                EntityMetadata subEntityMetadata = null;
                if (!subManagedType.isEmpty())
                {
                    for (AbstractManagedType subEntity : subManagedType)
                    {
                        String discColumn = subEntity.getDiscriminatorColumn();
                        String disColValue = subEntity.getDiscriminatorValue();
                        Object value = fetchedDocument.get(discColumn);
                        if (value != null && value.toString().equals(disColValue))
                        {
                            subEntityMetadata = KunderaMetadataManager.getEntityMetadata(kunderaMetadata,
                                    subEntity.getJavaType());
                            break;
                        }
                    }

                    enhancedEntity = instantiateEntity(subEntityMetadata.getEntityClazz(), enhancedEntity);
                    relationValue = handler.getEntityFromDocument(subEntityMetadata.getEntityClazz(), enhancedEntity,
                            subEntityMetadata, fetchedDocument, subEntityMetadata.getRelationNames(), relationValue,
                            kunderaMetadata);
                }
                else
                {
                    enhancedEntity = instantiateEntity(entityClass, enhancedEntity);
                    relationValue = handler.getEntityFromDocument(entityMetadata.getEntityClazz(), enhancedEntity,
                            entityMetadata, fetchedDocument, relationNames, relationValue, kunderaMetadata);
                }

            }
        }

        if (relationValue != null && !relationValue.isEmpty())
        {
            EnhanceEntity entity = new EnhanceEntity(enhancedEntity, PropertyAccessorHelper.getId(enhancedEntity,
                    entityMetadata), relationValue);
            return entity;
        }
        else
        {
            return enhancedEntity;
        }
    }