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);
}