protected void refreshObjectStateFromNativeEntry()

in grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/engine/NativeEntryEntityPersister.java [401:631]


    protected void refreshObjectStateFromNativeEntry(PersistentEntity persistentEntity, Object obj,
                                                     Serializable nativeKey, T nativeEntry, boolean isEmbedded) {
        EntityAccess ea = createEntityAccess(persistentEntity, obj, nativeEntry);

        if (!(persistentEntity instanceof EmbeddedPersistentEntity)) {
            String idName = ea.getIdentifierName();
            ea.setProperty(idName, nativeKey);
        }

        final List<PersistentProperty> props = persistentEntity.getPersistentProperties();
        for (final PersistentProperty prop : props) {
            String propKey = getNativePropertyKey(prop);
            if (prop instanceof Simple) {
                // this magically converts most types to the correct property type, using bean converters.
                ea.setProperty(prop.getName(), getEntryValue(nativeEntry, propKey));
            }
            else if (prop instanceof Basic) {
                Basic basic = (Basic) prop;
                CustomTypeMarshaller customTypeMarshaller = basic.getCustomTypeMarshaller();
                if(customTypeMarshaller != null) {
                    if (!customTypeMarshaller.supports(getMappingContext())) {
                        return;
                    }

                    Object value = customTypeMarshaller.read(prop, nativeEntry);
                    ea.setProperty(prop.getName(), value);
                }
                else {
                    Object entryValue = getEntryValue(nativeEntry, propKey);
                    entryValue = convertBasicEntryValue(persistentEntity, (Basic)prop, entryValue);
                    ea.setProperty(prop.getName(), entryValue);
                }
            }
            else if (prop instanceof Custom) {
                handleCustom(prop, ea, nativeEntry);
            }
            else if (prop instanceof ToOne) {
                if (prop instanceof Embedded) {
                    Embedded embedded = (Embedded) prop;
                    if(embedded.getAssociatedEntity() != null) {

                        T embeddedEntry = getEmbedded(nativeEntry, propKey);


                        if (embeddedEntry != null) {
                            Object embeddedInstance =
                                    createObjectFromEmbeddedNativeEntry(embedded.getAssociatedEntity(), embeddedEntry);

                            ea.setProperty(propKey, embeddedInstance);
                            cacheEmbeddedEntry(embedded.getAssociatedEntity(), createEmbeddedCacheEntryKey(embeddedInstance), embeddedEntry);
                            Association inverseSide = embedded.getInverseSide();
                            if (embedded.isBidirectional() && inverseSide != null) {
                                // fix up the owner link
                                EntityAccess embeddedEa =
                                        createEntityAccess(embedded.getAssociatedEntity(), embeddedInstance);
                                embeddedEa.setProperty(inverseSide.getName(), obj);
                            }
                        }
                    }
                }
                else {
                    ToOne association = (ToOne) prop;

                    Serializable tmp = null;
                    if (!association.isForeignKeyInChild()) {
                        tmp = (Serializable) getEntryValue(nativeEntry, propKey);
                    }
                    else {
                        if (association.isBidirectional() && association.getAssociatedEntity() != null) {

                            Query query = session.createQuery(association.getAssociatedEntity().getJavaClass());
                            query.eq(association.getInverseSide().getName(), obj)
                                  .projections().id();

                            tmp = (Serializable) query.singleResult();
                        }
                        else {
                            // TODO: handle unidirectional?
                        }
                    }

                    if (isEmbeddedEntry(tmp)) {
                        PersistentEntity associatedEntity = ((ToOne) prop).getAssociatedEntity();
                        associatedEntity = discriminatePersistentEntity(associatedEntity, (T) tmp);
                        Object instance = newEntityInstance(associatedEntity);
                        refreshObjectStateFromNativeEntry(associatedEntity,instance, null, (T) tmp, false);
                        ea.setProperty(prop.getName(), instance);
                    }
                    else if (tmp != null && !prop.getType().isInstance(tmp)) {
                        PersistentEntity associatedEntity = association.getAssociatedEntity();
                        if(associatedEntity != null) {
                            final Serializable associationKey = convertIdIfNecessary(associatedEntity, tmp);
                            if (associationKey != null) {

                                PropertyMapping<Property> associationPropertyMapping = prop.getMapping();
                                boolean isLazy = isLazyAssociation(associationPropertyMapping);

                                final Class propType = prop.getType();
                                Object value = isLazy ?
                                        session.proxy(propType, associationKey) :
                                        session.retrieve(propType, associationKey);
                                ea.setProperty(prop.getName(), value);
                            }
                        }
                    }
                }
            }
            else if (prop instanceof EmbeddedCollection) {
                final Object embeddedInstances = getEntryValue(nativeEntry, propKey);
                EmbeddedCollection embeddedCollection = (EmbeddedCollection) prop;
                loadEmbeddedCollection(embeddedCollection, ea, embeddedInstances, propKey);
                Association inverseSide = embeddedCollection.getInverseSide();
                if (embeddedCollection.isBidirectional() && inverseSide != null) {
                    // fix up the inverse link
                    Object loadedInstances = ea.getProperty(embeddedCollection.getName());
                    if (loadedInstances instanceof Collection) {
                        Collection embeddedInstancesCollection = (Collection) loadedInstances;
                        for (Object embeddedInstance : embeddedInstancesCollection) {
                            if (embeddedInstance != null) {
                                EntityAccess embeddedEa =
                                        createEntityAccess(embeddedCollection.getAssociatedEntity(), embeddedInstance);
                                embeddedEa.setProperty(inverseSide.getName(), obj);
                            }
                        }
                    }
                }
            }
            else if (prop instanceof OneToMany) {
                Association association = (Association) prop;
                PropertyMapping<Property> associationPropertyMapping = association.getMapping();

                if (isEmbedded) {
                    List keys = loadEmbeddedCollectionKeys((Association) prop, ea, nativeEntry);
                    if (List.class.isAssignableFrom(association.getType())) {
                        ea.setPropertyNoConversion(association.getName(),
                                new PersistentList(keys, association.getAssociatedEntity().getJavaClass(), session));
                    }
                    else if (Set.class.isAssignableFrom(association.getType())) {
                        ea.setPropertyNoConversion(association.getName(),
                                new PersistentSet(keys, association.getAssociatedEntity().getJavaClass(), session));
                    }
                }
                else {
                    boolean isLazy = isLazyAssociation(associationPropertyMapping);
                    AssociationIndexer indexer = getAssociationIndexer(nativeEntry, association);
                    if(indexer != null) {
                        nativeKey = convertIdIfNecessary(getPersistentEntity(), nativeKey );
                        if (isLazy) {
                            if (List.class.isAssignableFrom(association.getType())) {
                                ea.setPropertyNoConversion(association.getName(),
                                        new PersistentList(nativeKey, session, indexer));
                            }
                            else if (SortedSet.class.isAssignableFrom(association.getType())) {
                                ea.setPropertyNoConversion(association.getName(),
                                        new PersistentSortedSet(nativeKey, session, indexer));
                            }
                            else if (Set.class.isAssignableFrom(association.getType())) {
                                ea.setPropertyNoConversion(association.getName(),
                                        new PersistentSet(nativeKey, session, indexer));
                            }
                        }
                        else {
                            if (indexer != null) {
                                List keys = indexer.query(nativeKey);
                                ea.setProperty(association.getName(),
                                        session.retrieveAll(association.getAssociatedEntity().getJavaClass(), keys));
                            }
                        }
                    }
                }
            }
            else if (prop instanceof ManyToMany) {
                ManyToMany manyToMany = (ManyToMany) prop;
                PropertyMapping<Property> associationPropertyMapping = manyToMany.getMapping();

                boolean isLazy = isLazyAssociation(associationPropertyMapping);
                nativeKey = convertIdIfNecessary(getPersistentEntity(), nativeKey);
                PersistentEntity associatedEntity = manyToMany.getAssociatedEntity();
                if(associatedEntity != null) {

                    Class childType = associatedEntity.getJavaClass();
                    Collection cached = ((SessionImplementor)session).getCachedCollection(
                            persistentEntity, nativeKey, manyToMany.getName());
                    if (cached == null) {
                        Collection collection;
                        if (isLazy) {
                            Collection keys = getManyToManyKeys(persistentEntity, obj, nativeKey,
                                    nativeEntry, manyToMany);
                            if (List.class.isAssignableFrom(manyToMany.getType())) {
                                collection = new PersistentList(keys, childType, session);
                                ea.setPropertyNoConversion(manyToMany.getName(), collection);
                            }
                            else if (Set.class.isAssignableFrom(manyToMany.getType())) {
                                collection = new PersistentSet(keys, childType, session);
                                ea.setPropertyNoConversion(manyToMany.getName(), collection);
                            }
                            else {
                                collection = Collections.emptyList();
                            }
                        }
                        else {
                            AssociationIndexer indexer = getAssociationIndexer(nativeEntry, manyToMany);
                            if (indexer == null) {
                                if (List.class.isAssignableFrom(manyToMany.getType())) {
                                    collection = Collections.emptyList();
                                }
                                else if (Set.class.isAssignableFrom(manyToMany.getType())) {
                                    collection = Collections.emptySet();
                                }
                                else {
                                    collection = Collections.emptyList();
                                }
                            }
                            else {
                                List keys = indexer.query(nativeKey);
                                collection = session.retrieveAll(childType, keys);
                                ea.setProperty(manyToMany.getName(), collection);
                            }
                        }
                        ((SessionImplementor)session).cacheCollection(
                                persistentEntity, nativeKey, collection, manyToMany.getName());
                    }
                    else {
                        ea.setProperty(manyToMany.getName(), cached);
                    }
                }
            }
        }
        // entity is now fully loaded.
        firePostLoadEvent(persistentEntity, ea);
    }