use of org.apache.cayenne.ObjectId in project cayenne by apache.
the class DataDomainIndirectDiffBuilder method arcCreated.
@Override
public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
ObjEntity entity = resolver.getObjEntity(((ObjectId) nodeId).getEntityName());
ObjRelationship relationship = entity.getRelationship(arcId.toString());
if (relationship.isSourceIndependentFromTargetChange()) {
ObjectId nodeObjectId = (ObjectId) nodeId;
if (!nodeObjectId.isTemporary()) {
indirectModifications.add(nodeObjectId);
}
if (relationship.isFlattened()) {
if (relationship.isReadOnly()) {
throw new CayenneRuntimeException("Cannot set the read-only flattened relationship '%s' in ObjEntity '%s'.", relationship.getName(), relationship.getSourceEntity().getName());
}
// Register this combination (so we can remove it later if an insert occurs before commit)
FlattenedArcKey key = new FlattenedArcKey((ObjectId) nodeId, (ObjectId) targetNodeId, relationship);
// If this combination has already been deleted, simply undelete it.
if (!flattenedDeletes.remove(key)) {
flattenedInserts.add(key);
}
}
}
}
use of org.apache.cayenne.ObjectId in project cayenne by apache.
the class DataDomainQueryAction method interceptRelationshipQuery.
private boolean interceptRelationshipQuery() {
if (query instanceof RelationshipQuery) {
RelationshipQuery relationshipQuery = (RelationshipQuery) query;
if (relationshipQuery.isRefreshing()) {
return !DONE;
}
ObjRelationship relationship = relationshipQuery.getRelationship(domain.getEntityResolver());
// check if we can derive target PK from FK...
if (relationship.isSourceIndependentFromTargetChange()) {
return !DONE;
}
// we can assume that there is one and only one DbRelationship as
// we previously checked that "!isSourceIndependentFromTargetChange"
DbRelationship dbRelationship = relationship.getDbRelationships().get(0);
// FK pointing to a unique field that is a 'fake' PK (CAY-1755)...
// It is not sufficient to generate target ObjectId.
DbEntity targetEntity = dbRelationship.getTargetEntity();
if (dbRelationship.getJoins().size() < targetEntity.getPrimaryKeys().size()) {
return !DONE;
}
if (cache == null) {
return !DONE;
}
DataRow sourceRow = cache.getCachedSnapshot(relationshipQuery.getObjectId());
if (sourceRow == null) {
return !DONE;
}
ObjectId targetId = sourceRow.createTargetObjectId(relationship.getTargetEntityName(), dbRelationship);
// null id means that FK is null...
if (targetId == null) {
this.response = new GenericResponse(Collections.EMPTY_LIST);
return DONE;
}
// target id resolution (unlike source) should be polymorphic
DataRow targetRow = polymorphicRowFromCache(targetId);
if (targetRow != null) {
this.response = new GenericResponse(Collections.singletonList(targetRow));
return DONE;
}
// create a fault
if (context != null && relationship.isSourceDefiningTargetPrecenseAndType(domain.getEntityResolver())) {
// prevent passing partial snapshots to ObjectResolver per
// CAY-724.
// Create a hollow object right here and skip object conversion
// downstream
this.noObjectConversion = true;
Object object = context.findOrCreateObject(targetId);
this.response = new GenericResponse(Collections.singletonList(object));
return DONE;
}
}
return !DONE;
}
use of org.apache.cayenne.ObjectId in project cayenne by apache.
the class DataDomainQueryAction method polymorphicRowFromCache.
private DataRow polymorphicRowFromCache(EntityInheritanceTree superNode, Map<String, ?> idSnapshot) {
for (EntityInheritanceTree child : superNode.getChildren()) {
ObjectId id = new ObjectId(child.getEntity().getName(), idSnapshot);
DataRow row = cache.getCachedSnapshot(id);
if (row != null) {
return row;
}
row = polymorphicRowFromCache(child, idSnapshot);
if (row != null) {
return row;
}
}
return null;
}
use of org.apache.cayenne.ObjectId in project cayenne by apache.
the class DataDomainQueryAction method interceptRefreshQuery.
/**
* @since 3.0
*/
private boolean interceptRefreshQuery() {
if (query instanceof RefreshQuery) {
RefreshQuery refreshQuery = (RefreshQuery) query;
if (refreshQuery.isRefreshAll()) {
// not sending any events - peer contexts will not get refreshed
if (domain.getSharedSnapshotCache() != null) {
domain.getSharedSnapshotCache().clear();
} else {
// remove snapshots from local ObjectStore only
context.getObjectStore().getDataRowCache().clear();
}
context.getQueryCache().clear();
GenericResponse response = new GenericResponse();
response.addUpdateCount(1);
this.response = response;
return DONE;
}
Collection<Persistent> objects = (Collection<Persistent>) refreshQuery.getObjects();
if (objects != null && !objects.isEmpty()) {
Collection<ObjectId> ids = new ArrayList<>(objects.size());
for (final Persistent object : objects) {
ids.add(object.getObjectId());
}
if (domain.getSharedSnapshotCache() != null) {
// send an event for removed snapshots
domain.getSharedSnapshotCache().processSnapshotChanges(context.getObjectStore(), Collections.EMPTY_MAP, Collections.EMPTY_LIST, ids, Collections.EMPTY_LIST);
} else {
// remove snapshots from local ObjectStore only
context.getObjectStore().getDataRowCache().processSnapshotChanges(context.getObjectStore(), Collections.EMPTY_MAP, Collections.EMPTY_LIST, ids, Collections.EMPTY_LIST);
}
GenericResponse response = new GenericResponse();
response.addUpdateCount(1);
this.response = response;
return DONE;
}
// usually does a cascading refresh
if (refreshQuery.getQuery() != null) {
Query cachedQuery = refreshQuery.getQuery();
String cacheKey = cachedQuery.getMetaData(context.getEntityResolver()).getCacheKey();
context.getQueryCache().remove(cacheKey);
this.response = domain.onQuery(context, cachedQuery);
return DONE;
}
// 4. refresh groups...
if (refreshQuery.getGroupKeys() != null && refreshQuery.getGroupKeys().length > 0) {
String[] groups = refreshQuery.getGroupKeys();
for (String group : groups) {
domain.getQueryCache().removeGroup(group);
}
GenericResponse response = new GenericResponse();
response.addUpdateCount(1);
this.response = response;
return DONE;
}
}
return !DONE;
}
use of org.apache.cayenne.ObjectId in project cayenne by apache.
the class DataNodeSyncQualifierDescriptor method reset.
void reset(DbEntityClassDescriptor descriptor) {
attributes = new ArrayList<>(3);
valueTransformers = new ArrayList<>(3);
usingOptimisticLocking = descriptor.getEntity().getLockType() == ObjEntity.LOCK_TYPE_OPTIMISTIC;
// master PK columns
if (descriptor.isMaster()) {
for (final DbAttribute attribute : descriptor.getDbEntity().getPrimaryKeys()) {
attributes.add(attribute);
valueTransformers.add(input -> {
ObjectId id = (ObjectId) input.getNodeId();
return id.getIdSnapshot().get(attribute.getName());
});
}
} else {
// TODO: andrus 12/23/2007 - only one step relationship is supported...
if (descriptor.getPathFromMaster().size() != 1) {
throw new CayenneRuntimeException("Only single step dependent relationships are currently supported. Actual path length: %d", descriptor.getPathFromMaster().size());
}
DbRelationship masterDependentDbRel = descriptor.getPathFromMaster().get(0);
if (masterDependentDbRel != null) {
for (final DbJoin dbAttrPair : masterDependentDbRel.getJoins()) {
DbAttribute dbAttribute = dbAttrPair.getTarget();
if (!attributes.contains(dbAttribute)) {
attributes.add(dbAttribute);
valueTransformers.add(input -> {
ObjectId id = (ObjectId) input.getNodeId();
return id.getIdSnapshot().get(dbAttrPair.getSourceName());
});
}
}
}
}
if (usingOptimisticLocking) {
for (final ObjAttribute attribute : descriptor.getEntity().getAttributes()) {
if (attribute.isUsedForLocking()) {
// only care about first step in a flattened attribute
DbAttribute dbAttribute = (DbAttribute) attribute.getDbPathIterator().next();
// only use qualifier if dbEntities match
if (dbAttribute.getEntity().equals(descriptor.getDbEntity()) && !attributes.contains(dbAttribute)) {
attributes.add(dbAttribute);
valueTransformers.add(input -> input.getSnapshotValue(attribute.getName()));
}
}
}
for (final ObjRelationship relationship : descriptor.getEntity().getRelationships()) {
if (relationship.isUsedForLocking()) {
// only care about the first DbRelationship
DbRelationship dbRelationship = relationship.getDbRelationships().get(0);
for (final DbJoin dbAttrPair : dbRelationship.getJoins()) {
DbAttribute dbAttribute = dbAttrPair.getSource();
// relationship transformers override attribute transformers for meaningful FK's...
// why meaningful FKs can go out of sync is another story (CAY-595)
int index = attributes.indexOf(dbAttribute);
if (index >= 0 && !dbAttribute.isForeignKey()) {
continue;
}
Function<ObjectDiff, Object> transformer = input -> {
ObjectId targetId = input.getArcSnapshotValue(relationship.getName());
return targetId != null ? targetId.getIdSnapshot().get(dbAttrPair.getTargetName()) : null;
};
if (index < 0) {
attributes.add(dbAttribute);
valueTransformers.add(transformer);
} else {
valueTransformers.set(index, transformer);
}
}
}
}
}
}
Aggregations