info.archinnov.achilles.entity.operations.ThriftEntityMerger Maven / Gradle / Ivy
package info.archinnov.achilles.entity.operations;
import static info.archinnov.achilles.entity.metadata.PropertyType.*;
import static javax.persistence.CascadeType.*;
import info.archinnov.achilles.context.AchillesPersistenceContext;
import info.archinnov.achilles.context.ThriftPersistenceContext;
import info.archinnov.achilles.entity.metadata.EntityMeta;
import info.archinnov.achilles.entity.metadata.JoinProperties;
import info.archinnov.achilles.entity.metadata.PropertyMeta;
import info.archinnov.achilles.entity.metadata.PropertyType;
import info.archinnov.achilles.proxy.AchillesEntityInterceptor;
import info.archinnov.achilles.proxy.AchillesMethodInvoker;
import info.archinnov.achilles.validation.Validator;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.persistence.CascadeType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Sets;
/**
* ThriftEntityMerger
*
* @author DuyHai DOAN
*
*/
public class ThriftEntityMerger implements AchillesEntityMerger
{
private static final Logger log = LoggerFactory.getLogger(ThriftEntityMerger.class);
private ThriftEntityPersister persister = new ThriftEntityPersister();
private AchillesMethodInvoker invoker = new AchillesMethodInvoker();
private AchillesEntityProxifier proxifier = new ThriftEntityProxifier();
private Set multiValueTypes = Sets.newHashSet(LIST, LAZY_LIST, SET, LAZY_SET,
MAP, LAZY_MAP);
@Override
public T mergeEntity(AchillesPersistenceContext context, T entity)
{
log.debug("Merging entity of class {} with primary key {}", context
.getEntityClass()
.getCanonicalName(), context.getPrimaryKey());
ThriftPersistenceContext thriftContext = (ThriftPersistenceContext) context;
EntityMeta entityMeta = context.getEntityMeta();
Validator.validateNotNull(entity, "Proxy object should not be null");
Validator.validateNotNull(entityMeta, "entityMeta should not be null");
T proxy;
if (proxifier.isProxy(entity))
{
log.debug("Checking for dirty fields before merging");
T realObject = proxifier.getRealObject(entity);
AchillesEntityInterceptor interceptor = proxifier.getInterceptor(entity);
Map> dirtyMap = interceptor.getDirtyMap();
if (dirtyMap.size() > 0)
{
for (Entry> entry : dirtyMap.entrySet())
{
PropertyMeta, ?> propertyMeta = entry.getValue();
if (multiValueTypes.contains(propertyMeta.type()))
{
log.debug("Removing dirty collection/map {} before merging",
propertyMeta.getPropertyName());
persister.removePropertyBatch(thriftContext, propertyMeta);
}
persister.persistProperty(context, propertyMeta);
}
}
dirtyMap.clear();
for (Entry> entry : entityMeta.getPropertyMetas().entrySet())
{
PropertyMeta, ?> propertyMeta = entry.getValue();
if (propertyMeta.isJoin())
{
Set cascadeTypes = propertyMeta
.getJoinProperties()
.getCascadeTypes();
if (cascadeTypes.contains(MERGE) || cascadeTypes.contains(ALL))
{
log.debug("Cascade-merging join property {}",
propertyMeta.getPropertyName());
switch (propertyMeta.type())
{
case JOIN_SIMPLE:
mergeJoinProperty(thriftContext, realObject, propertyMeta);
break;
case JOIN_LIST:
mergeJoinListProperty(thriftContext, realObject, propertyMeta);
break;
case JOIN_SET:
mergeJoinSetProperty(thriftContext, realObject, propertyMeta);
break;
case JOIN_MAP:
mergeJoinMapProperty(thriftContext, realObject, propertyMeta);
break;
default:
break;
}
}
}
}
interceptor.setContext(thriftContext);
interceptor.setTarget(realObject);
proxy = entity;
}
else
{
log.debug("Persisting transient entity");
if (!context.isWideRow())
{
this.persister.persist(context);
}
proxy = proxifier.buildProxy(entity, context);
}
return proxy;
}
private void mergeJoinProperty(ThriftPersistenceContext context, T entity,
PropertyMeta, ?> propertyMeta)
{
JoinProperties joinProperties = propertyMeta.getJoinProperties();
Object joinEntity = invoker.getValueFromField(entity, propertyMeta.getGetter());
if (joinEntity != null)
{
log.debug("Merging join entity {} ", joinEntity);
Object mergedEntity = mergeEntity(
context.newPersistenceContext(joinProperties.getEntityMeta(), joinEntity),
joinEntity);
invoker.setValueToField(entity, propertyMeta.getSetter(), mergedEntity);
}
}
private void mergeJoinListProperty(ThriftPersistenceContext context, Object entity,
PropertyMeta, ?> propertyMeta)
{
JoinProperties joinProperties = propertyMeta.getJoinProperties();
List> joinEntities = (List>) invoker
.getValueFromField(entity, propertyMeta.getGetter());
List © 2015 - 2025 Weber Informatics LLC | Privacy Policy