Search in sources :

Example 51 with ObjRelationship

use of org.apache.cayenne.map.ObjRelationship in project cayenne by apache.

the class DataContextPrefetchIT method testPrefetch_ToManyNoReverse.

/**
 * Test that a to-many relationship is initialized when there is no inverse
 * relationship
 */
@Test
public void testPrefetch_ToManyNoReverse() throws Exception {
    createTwoArtistsAndTwoPaintingsDataSet();
    ObjEntity paintingEntity = context.getEntityResolver().getObjEntity(Painting.class);
    ObjRelationship relationship = paintingEntity.getRelationship("toArtist");
    paintingEntity.removeRelationship("toArtist");
    try {
        SelectQuery<Artist> q = new SelectQuery<>(Artist.class);
        q.addPrefetch(Artist.PAINTING_ARRAY.disjoint());
        final List<Artist> result = context.performQuery(q);
        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {

            public void execute() {
                assertFalse(result.isEmpty());
                Artist a1 = result.get(0);
                List<?> toMany = (List<?>) a1.readPropertyDirectly("paintingArray");
                assertNotNull(toMany);
                assertFalse(((ValueHolder) toMany).isFault());
            }
        });
    } finally {
        paintingEntity.addRelationship(relationship);
    }
}
Also used : Artist(org.apache.cayenne.testdo.testmap.Artist) SelectQuery(org.apache.cayenne.query.SelectQuery) ObjEntity(org.apache.cayenne.map.ObjEntity) ObjRelationship(org.apache.cayenne.map.ObjRelationship) UnitTestClosure(org.apache.cayenne.unit.di.UnitTestClosure) List(java.util.List) ValueHolder(org.apache.cayenne.ValueHolder) Test(org.junit.Test)

Example 52 with ObjRelationship

use of org.apache.cayenne.map.ObjRelationship in project cayenne by apache.

the class Compiler method compileEntityResultWithPrefetch.

private EntityResult compileEntityResultWithPrefetch(EntityResult compiledResult, EJBQLExpression prefetchExpression) {
    final EntityResult result = compiledResult;
    String id = prefetchExpression.getText().toLowerCase();
    ClassDescriptor descriptor = descriptorsById.get(id);
    if (descriptor == null) {
        descriptor = descriptorsById.get(prefetchExpression.getText());
    }
    final String prefix = prefetchExpression.getText().substring(prefetchExpression.getText().indexOf(".") + 1);
    final Set<String> visited = new HashSet<String>();
    PropertyVisitor visitor = new PropertyVisitor() {

        public boolean visitAttribute(AttributeProperty property) {
            ObjAttribute oa = property.getAttribute();
            if (visited.add(oa.getDbAttributePath())) {
                result.addObjectField(oa.getEntity().getName(), "fetch." + prefix + "." + oa.getName(), prefix + "." + oa.getDbAttributeName());
            }
            return true;
        }

        public boolean visitToMany(ToManyProperty property) {
            return true;
        }

        public boolean visitToOne(ToOneProperty property) {
            ObjRelationship rel = property.getRelationship();
            DbRelationship dbRel = rel.getDbRelationships().get(0);
            for (DbJoin join : dbRel.getJoins()) {
                DbAttribute src = join.getSource();
                if (src.isForeignKey() && visited.add(src.getName())) {
                    result.addDbField("fetch." + prefix + "." + src.getName(), prefix + "." + src.getName());
                }
            }
            return true;
        }
    };
    descriptor.visitAllProperties(visitor);
    // append id columns ... (some may have been appended already via relationships)
    for (String pkName : descriptor.getEntity().getPrimaryKeyNames()) {
        if (visited.add(pkName)) {
            result.addDbField("fetch." + prefix + "." + pkName, prefix + "." + pkName);
        }
    }
    // append inheritance discriminator columns...
    for (ObjAttribute column : descriptor.getDiscriminatorColumns()) {
        if (visited.add(column.getName())) {
            result.addDbField("fetch." + prefix + "." + column.getDbAttributePath(), prefix + "." + column.getDbAttributePath());
        }
    }
    return result;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ObjAttribute(org.apache.cayenne.map.ObjAttribute) DbAttribute(org.apache.cayenne.map.DbAttribute) EntityResult(org.apache.cayenne.map.EntityResult) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor) HashSet(java.util.HashSet)

Example 53 with ObjRelationship

use of org.apache.cayenne.map.ObjRelationship in project cayenne by apache.

the class Compiler method compile.

CompiledExpression compile(String source, EJBQLExpression parsed) {
    parsed.visit(new CompilationVisitor());
    Map<EJBQLPath, Integer> pathsInSelect = new HashMap<>();
    for (int i = 0; i < parsed.getChildrenCount(); i++) {
        if (parsed.getChild(i) instanceof EJBQLSelectClause) {
            EJBQLExpression parsedTemp = parsed.getChild(i);
            boolean stop = false;
            while (parsedTemp.getChildrenCount() > 0 && !stop) {
                EJBQLExpression newParsedTemp = null;
                for (int j = 0; j < parsedTemp.getChildrenCount(); j++) {
                    if (parsedTemp.getChild(j) instanceof EJBQLSelectExpression) {
                        for (int k = 0; k < parsedTemp.getChild(j).getChildrenCount(); k++) {
                            if (parsedTemp.getChild(j).getChild(k) instanceof EJBQLPath) {
                                pathsInSelect.put((EJBQLPath) parsedTemp.getChild(j).getChild(k), j);
                            }
                        }
                    } else {
                        if (parsedTemp.getChild(j).getChildrenCount() == 0) {
                            stop = true;
                        } else {
                            newParsedTemp = parsedTemp.getChild(j);
                        }
                    }
                }
                if (!stop && newParsedTemp != null) {
                    parsedTemp = newParsedTemp;
                } else {
                    stop = true;
                }
            }
        }
    }
    // postprocess paths, now that all id vars are resolved
    if (paths != null) {
        for (EJBQLPath path : paths) {
            String id = normalizeIdPath(path.getId());
            ClassDescriptor descriptor = descriptorsById.get(id);
            if (descriptor == null) {
                throw new EJBQLException("Unmapped id variable: " + id);
            }
            StringBuilder buffer = new StringBuilder(id);
            ObjRelationship incoming = null;
            String pathRelationshipString = "";
            for (int i = 1; i < path.getChildrenCount(); i++) {
                String pathChunk = path.getChild(i).getText();
                if (pathChunk.endsWith(Entity.OUTER_JOIN_INDICATOR)) {
                    pathChunk = pathChunk.substring(0, pathChunk.length() - 1);
                }
                buffer.append('.').append(pathChunk);
                PropertyDescriptor property = descriptor.getProperty(pathChunk);
                if (property instanceof ArcProperty) {
                    incoming = ((ArcProperty) property).getRelationship();
                    descriptor = ((ArcProperty) property).getTargetDescriptor();
                    pathRelationshipString = buffer.substring(0, buffer.length());
                    descriptorsById.put(pathRelationshipString, descriptor);
                    incomingById.put(pathRelationshipString, incoming);
                }
            }
            if (pathsInSelect.size() > 0 && incoming != null && pathRelationshipString.length() > 0 && pathRelationshipString.equals(buffer.toString())) {
                EJBQLIdentifier ident = new EJBQLIdentifier(0);
                ident.text = pathRelationshipString;
                Integer integer = pathsInSelect.get(path);
                if (integer != null) {
                    resultComponents.remove(integer.intValue());
                    resultComponents.add(integer, ident);
                    rootId = pathRelationshipString;
                }
            }
        }
    }
    CompiledExpression compiled = new CompiledExpression();
    compiled.setExpression(parsed);
    compiled.setSource(source);
    compiled.setRootId(rootId);
    compiled.setDescriptorsById(descriptorsById);
    compiled.setIncomingById(incomingById);
    compiled.setPrefetchTree(prefetchTree);
    if (resultComponents != null) {
        SQLResult mapping = new SQLResult();
        for (int i = 0; i < resultComponents.size(); i++) {
            Object nextMapping = resultComponents.get(i);
            if (nextMapping instanceof String) {
                mapping.addColumnResult((String) nextMapping);
            } else if (nextMapping instanceof EJBQLExpression) {
                EntityResult compileEntityResult = compileEntityResult((EJBQLExpression) nextMapping, i);
                if (prefetchTree != null) {
                    for (PrefetchTreeNode prefetch : prefetchTree.getChildren()) {
                        if (((EJBQLExpression) nextMapping).getText().equals(prefetch.getEjbqlPathEntityId())) {
                            EJBQLIdentifier ident = new EJBQLIdentifier(0);
                            ident.text = prefetch.getEjbqlPathEntityId() + "." + prefetch.getPath();
                            compileEntityResult = compileEntityResultWithPrefetch(compileEntityResult, ident);
                        }
                    }
                }
                mapping.addEntityResult(compileEntityResult);
            }
        }
        compiled.setResult(mapping);
    }
    return compiled;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) PropertyDescriptor(org.apache.cayenne.reflect.PropertyDescriptor) HashMap(java.util.HashMap) EJBQLException(org.apache.cayenne.ejbql.EJBQLException) EntityResult(org.apache.cayenne.map.EntityResult) EJBQLCompiledExpression(org.apache.cayenne.ejbql.EJBQLCompiledExpression) SQLResult(org.apache.cayenne.map.SQLResult) PrefetchTreeNode(org.apache.cayenne.query.PrefetchTreeNode) EJBQLExpression(org.apache.cayenne.ejbql.EJBQLExpression)

Example 54 with ObjRelationship

use of org.apache.cayenne.map.ObjRelationship in project cayenne by apache.

the class Compiler method compileEntityResult.

private EntityResult compileEntityResult(EJBQLExpression expression, int position) {
    String id = expression.getText().toLowerCase();
    ClassDescriptor descriptor = descriptorsById.get(id);
    if (descriptor == null) {
        descriptor = descriptorsById.get(expression.getText());
    }
    if (descriptor == null) {
        throw new EJBQLException("the entity variable '" + id + "' does not refer to any entity in the FROM clause");
    }
    final EntityResult entityResult = new EntityResult(descriptor.getObjectClass());
    final String prefix = "ec" + position + "_";
    final int[] index = { 0 };
    final Set<String> visited = new HashSet<String>();
    PropertyVisitor visitor = new PropertyVisitor() {

        public boolean visitAttribute(AttributeProperty property) {
            ObjAttribute oa = property.getAttribute();
            if (visited.add(oa.getDbAttributePath())) {
                entityResult.addObjectField(oa.getEntity().getName(), oa.getName(), prefix + index[0]++);
            }
            return true;
        }

        public boolean visitToMany(ToManyProperty property) {
            return true;
        }

        public boolean visitToOne(ToOneProperty property) {
            ObjRelationship rel = property.getRelationship();
            DbRelationship dbRel = rel.getDbRelationships().get(0);
            for (DbJoin join : dbRel.getJoins()) {
                DbAttribute src = join.getSource();
                if (src.isForeignKey() && visited.add(src.getName())) {
                    entityResult.addDbField(src.getName(), prefix + index[0]++);
                }
            }
            return true;
        }
    };
    descriptor.visitAllProperties(visitor);
    // append id columns ... (some may have been appended already via relationships)
    for (String pkName : descriptor.getEntity().getPrimaryKeyNames()) {
        if (visited.add(pkName)) {
            entityResult.addDbField(pkName, prefix + index[0]++);
        }
    }
    // append inheritance discriminator columns...
    for (ObjAttribute column : descriptor.getDiscriminatorColumns()) {
        if (visited.add(column.getName())) {
            entityResult.addDbField(column.getDbAttributePath(), prefix + index[0]++);
        }
    }
    return entityResult;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ObjAttribute(org.apache.cayenne.map.ObjAttribute) EJBQLException(org.apache.cayenne.ejbql.EJBQLException) DbAttribute(org.apache.cayenne.map.DbAttribute) EntityResult(org.apache.cayenne.map.EntityResult) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor) HashSet(java.util.HashSet)

Example 55 with ObjRelationship

use of org.apache.cayenne.map.ObjRelationship in project cayenne by apache.

the class RelationshipQuery method createReplacementQuery.

@Override
protected Query createReplacementQuery(EntityResolver resolver) {
    if (objectId.isTemporary() && !objectId.isReplacementIdAttached()) {
        throw new CayenneRuntimeException("Can't build a query for relationship '%s' for temporary id: %s", relationshipName, objectId);
    }
    ObjRelationship relationship = getRelationship(resolver);
    // build executable select...
    Expression qualifier = ExpressionFactory.matchDbExp(relationship.getReverseDbRelationshipPath(), objectId);
    SelectQuery<Object> query = new SelectQuery<Object>((ObjEntity) relationship.getTargetEntity(), qualifier);
    query.setStatementFetchSize(statementFetchSize);
    return query;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) Expression(org.apache.cayenne.exp.Expression) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException)

Aggregations

ObjRelationship (org.apache.cayenne.map.ObjRelationship)84 ObjEntity (org.apache.cayenne.map.ObjEntity)48 ObjAttribute (org.apache.cayenne.map.ObjAttribute)27 DbRelationship (org.apache.cayenne.map.DbRelationship)26 Test (org.junit.Test)24 DbEntity (org.apache.cayenne.map.DbEntity)18 DbAttribute (org.apache.cayenne.map.DbAttribute)15 DbJoin (org.apache.cayenne.map.DbJoin)14 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)12 ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)12 ObjectId (org.apache.cayenne.ObjectId)10 ToManyProperty (org.apache.cayenne.reflect.ToManyProperty)9 ToOneProperty (org.apache.cayenne.reflect.ToOneProperty)9 ArrayList (java.util.ArrayList)8 AttributeProperty (org.apache.cayenne.reflect.AttributeProperty)8 PropertyVisitor (org.apache.cayenne.reflect.PropertyVisitor)8 List (java.util.List)7 EJBQLException (org.apache.cayenne.ejbql.EJBQLException)7 DataMap (org.apache.cayenne.map.DataMap)7 HashMap (java.util.HashMap)6