use of com.haulmont.cuba.core.entity.Entity in project cuba by cuba-platform.
the class PersistenceTools method getReferenceId.
/**
* Returns an ID of directly referenced entity without loading it from DB.
*
* If the view does not contain the reference and {@link View#loadPartialEntities()} is true,
* the returned {@link RefId} will have {@link RefId#isLoaded()} = false.
*
* <p>Usage example:
* <pre>
* PersistenceTools.RefId refId = persistenceTools.getReferenceId(doc, "currency");
* if (refId.isLoaded()) {
* String currencyCode = (String) refId.getValue();
* }
* </pre>
*
* @param entity entity instance in managed state
* @param property name of reference property
* @return {@link RefId} instance which contains the referenced entity ID
* @throws IllegalArgumentException if the specified property is not a reference
* @throws IllegalStateException if the entity is not in Managed state
* @throws RuntimeException if anything goes wrong when retrieving the ID
*/
public RefId getReferenceId(BaseGenericIdEntity entity, String property) {
MetaClass metaClass = metadata.getClassNN(entity.getClass());
MetaProperty metaProperty = metaClass.getPropertyNN(property);
if (!metaProperty.getRange().isClass() || metaProperty.getRange().getCardinality().isMany())
throw new IllegalArgumentException("Property is not a reference");
if (!PersistenceHelper.isManaged(entity))
throw new IllegalStateException("Entity must be in managed state");
String[] inaccessibleAttributes = BaseEntityInternalAccess.getInaccessibleAttributes(entity);
if (inaccessibleAttributes != null) {
for (String inaccessibleAttr : inaccessibleAttributes) {
if (inaccessibleAttr.equals(property))
return RefId.createNotLoaded(property);
}
}
if (entity instanceof FetchGroupTracker) {
FetchGroup fetchGroup = ((FetchGroupTracker) entity)._persistence_getFetchGroup();
if (fetchGroup != null) {
if (!fetchGroup.getAttributeNames().contains(property))
return RefId.createNotLoaded(property);
else {
Entity refEntity = (Entity) entity.getValue(property);
return RefId.create(property, refEntity == null ? null : refEntity.getId());
}
}
}
try {
Class<?> declaringClass = metaProperty.getDeclaringClass();
if (declaringClass == null) {
throw new RuntimeException("Property does not belong to persistent class");
}
Method vhMethod = declaringClass.getDeclaredMethod(String.format("_persistence_get_%s_vh", property));
vhMethod.setAccessible(true);
ValueHolderInterface vh = (ValueHolderInterface) vhMethod.invoke(entity);
if (vh instanceof DatabaseValueHolder) {
AbstractRecord row = ((DatabaseValueHolder) vh).getRow();
if (row != null) {
Session session = persistence.getEntityManager().getDelegate().unwrap(Session.class);
ClassDescriptor descriptor = session.getDescriptor(entity);
DatabaseMapping mapping = descriptor.getMappingForAttributeName(property);
Vector<DatabaseField> fields = mapping.getFields();
if (fields.size() != 1) {
throw new IllegalStateException("Invalid number of columns in mapping: " + fields);
}
Object value = row.get(fields.get(0));
if (value != null) {
ClassDescriptor refDescriptor = mapping.getReferenceDescriptor();
DatabaseMapping refMapping = refDescriptor.getMappingForAttributeName(metadata.getTools().getPrimaryKeyName(metaClass));
if (refMapping instanceof AbstractColumnMapping) {
Converter converter = ((AbstractColumnMapping) refMapping).getConverter();
if (converter != null) {
return RefId.create(property, converter.convertDataValueToObjectValue(value, session));
}
}
}
return RefId.create(property, value);
} else {
return RefId.create(property, null);
}
}
return RefId.createNotLoaded(property);
} catch (Exception e) {
throw new RuntimeException(String.format("Error retrieving reference ID from %s.%s", entity.getClass().getSimpleName(), property), e);
}
}
use of com.haulmont.cuba.core.entity.Entity in project cuba by cuba-platform.
the class AttributeAccessServiceBean method computeSecurityState.
@Override
public SecurityState computeSecurityState(Entity entity) {
Preconditions.checkNotNullArgument(entity, "entity is null");
SecurityState state;
String storeName = metadataTools.getStoreName(metadata.getClassNN(entity.getClass()));
Transaction tx = persistence.createTransaction(storeName);
try {
EntityManager em = persistence.getEntityManager(storeName);
Entity managedEntity = em.merge(entity);
support.setupAttributeAccess(managedEntity);
state = BaseEntityInternalAccess.getSecurityState(managedEntity);
// do not commit the transaction
} finally {
tx.end();
}
return state;
}
use of com.haulmont.cuba.core.entity.Entity in project cuba by cuba-platform.
the class CrossDataStoreReferenceLoader method loadBatch.
private void loadBatch(CrossDataStoreProperty crossDataStoreProperty, List<Entity> entities) {
List<Object> idList = entities.stream().map(e -> e.getValue(crossDataStoreProperty.relatedPropertyName)).filter(Objects::nonNull).distinct().collect(Collectors.toList());
if (idList.isEmpty())
return;
MetaClass cdsrMetaClass = crossDataStoreProperty.property.getRange().asClass();
LoadContext<Entity> loadContext = new LoadContext<>(cdsrMetaClass);
MetaProperty primaryKeyProperty = metadataTools.getPrimaryKeyProperty(cdsrMetaClass);
if (primaryKeyProperty == null || !primaryKeyProperty.getRange().isClass()) {
String queryString = String.format("select e from %s e where e.%s in :idList", cdsrMetaClass, crossDataStoreProperty.primaryKeyName);
loadContext.setQuery(LoadContext.createQuery(queryString).setParameter("idList", idList));
} else {
// composite key entity
StringBuilder sb = new StringBuilder("select e from ");
sb.append(cdsrMetaClass).append(" e where ");
MetaClass idMetaClass = primaryKeyProperty.getRange().asClass();
for (Iterator<MetaProperty> it = idMetaClass.getProperties().iterator(); it.hasNext(); ) {
MetaProperty property = it.next();
sb.append("e.").append(crossDataStoreProperty.primaryKeyName).append(".").append(property.getName());
sb.append(" in :list_").append(property.getName());
if (it.hasNext())
sb.append(" and ");
}
LoadContext.Query query = LoadContext.createQuery(sb.toString());
for (MetaProperty property : idMetaClass.getProperties()) {
List<Object> propList = idList.stream().map(o -> ((Entity) o).getValue(property.getName())).collect(Collectors.toList());
query.setParameter("list_" + property.getName(), propList);
}
loadContext.setQuery(query);
}
loadContext.setView(crossDataStoreProperty.viewProperty.getView());
List<Entity> loadedEntities = dataManager.loadList(loadContext);
for (Entity entity : entities) {
Object relatedPropertyValue = entity.getValue(crossDataStoreProperty.relatedPropertyName);
loadedEntities.stream().filter(e -> {
Object id = e.getId() instanceof IdProxy ? ((IdProxy) e.getId()).getNN() : e.getId();
return id.equals(relatedPropertyValue);
}).findAny().ifPresent(e -> entity.setValue(crossDataStoreProperty.property.getName(), e));
}
}
use of com.haulmont.cuba.core.entity.Entity in project cuba by cuba-platform.
the class CrossDataStoreReferenceLoader method loadOne.
private void loadOne(EntityCrossDataStoreProperty entityCrossDataStoreProperty) {
Entity entity = entityCrossDataStoreProperty.entity;
CrossDataStoreProperty aProp = entityCrossDataStoreProperty.crossProp;
Object id = entity.getValue(aProp.relatedPropertyName);
LoadContext<Entity> loadContext = new LoadContext<>(aProp.property.getRange().asClass());
loadContext.setId(id);
if (aProp.viewProperty.getView() != null)
loadContext.setView(aProp.viewProperty.getView());
Entity relatedEntity = dataManager.load(loadContext);
entity.setValue(aProp.property.getName(), relatedEntity);
}
use of com.haulmont.cuba.core.entity.Entity in project cuba by cuba-platform.
the class EntityDiffManager method getCollectionDiff.
protected EntityPropertyDiff getCollectionDiff(Object firstValue, Object secondValue, ViewProperty viewProperty, MetaProperty metaProperty, Stack<Object> diffBranch) {
EntityPropertyDiff propertyDiff = null;
Collection<Entity> addedEntities = new LinkedList<>();
Collection<Entity> removedEntities = new LinkedList<>();
Collection<Pair<Entity, Entity>> modifiedEntities = new LinkedList<>();
// collection
Collection firstCollection = firstValue == null ? Collections.emptyList() : (Collection) firstValue;
Collection secondCollection = secondValue == null ? Collections.emptyList() : (Collection) secondValue;
// added or modified
for (Object item : secondCollection) {
Entity secondEntity = (Entity) item;
Entity firstEntity = getRelatedItem(firstCollection, secondEntity);
if (firstEntity == null)
addedEntities.add(secondEntity);
else
modifiedEntities.add(new Pair<>(firstEntity, secondEntity));
}
// removed
for (Object item : firstCollection) {
Entity firstEntity = (Entity) item;
Entity secondEntity = getRelatedItem(secondCollection, firstEntity);
if (secondEntity == null)
removedEntities.add(firstEntity);
}
boolean changed = !(addedEntities.isEmpty() && removedEntities.isEmpty() && modifiedEntities.isEmpty());
if (changed) {
EntityCollectionPropertyDiff diff = new EntityCollectionPropertyDiff(metaProperty);
for (Entity entity : addedEntities) {
EntityPropertyDiff addedDiff = getClassDiff(null, entity, viewProperty, metaProperty, diffBranch);
if (addedDiff != null) {
addedDiff.setName(InstanceUtils.getInstanceName(entity));
addedDiff.setItemState(EntityPropertyDiff.ItemState.Added);
diff.getAddedEntities().add(addedDiff);
}
}
// check modified
for (Pair<Entity, Entity> entityPair : modifiedEntities) {
EntityPropertyDiff modifiedDiff = getClassDiff(entityPair.getFirst(), entityPair.getSecond(), viewProperty, metaProperty, diffBranch);
if (modifiedDiff != null) {
modifiedDiff.setName(InstanceUtils.getInstanceName(entityPair.getSecond()));
modifiedDiff.setItemState(EntityPropertyDiff.ItemState.Modified);
diff.getModifiedEntities().add(modifiedDiff);
}
}
// check removed
for (Entity entity : removedEntities) {
EntityPropertyDiff removedDiff = getClassDiff(entity, null, viewProperty, metaProperty, diffBranch);
if (removedDiff != null) {
removedDiff.setName(InstanceUtils.getInstanceName(entity));
removedDiff.setItemState(EntityPropertyDiff.ItemState.Removed);
diff.getRemovedEntities().add(removedDiff);
}
}
boolean empty = diff.getAddedEntities().isEmpty() && diff.getModifiedEntities().isEmpty() && diff.getRemovedEntities().isEmpty();
if (!empty)
propertyDiff = diff;
}
return propertyDiff;
}
Aggregations