Search in sources :

Example 46 with ObjAttribute

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

the class SelectQueryMetadata method buildEntityResultForColumn.

/**
 * Collect metadata for column that will be unwrapped to full entity in the final SQL
 * (possibly including joint prefetch).
 * This information will be used to correctly create Persistent object back from raw result.
 *
 * This method is actually repeating logic of
 * {@link org.apache.cayenne.access.translator.select.DefaultSelectTranslator#appendQueryColumns}.
 * Here we don't care about intermediate joins and few other things so it's shorter.
 * Logic of these methods should be unified and simplified, possibly to a single source of metadata,
 * generated only once and used everywhere.
 *
 * @param query original query
 * @param column full object column
 * @param resolver entity resolver to get ObjEntity and ClassDescriptor
 * @return Entity result
 */
private EntityResult buildEntityResultForColumn(SelectQuery<?> query, Property<?> column, EntityResolver resolver) {
    final EntityResult result = new EntityResult(column.getType());
    // Collecting visitor for ObjAttributes and toOne relationships
    PropertyVisitor visitor = new PropertyVisitor() {

        public boolean visitAttribute(AttributeProperty property) {
            ObjAttribute oa = property.getAttribute();
            Iterator<CayenneMapEntry> dbPathIterator = oa.getDbPathIterator();
            while (dbPathIterator.hasNext()) {
                CayenneMapEntry pathPart = dbPathIterator.next();
                if (pathPart instanceof DbAttribute) {
                    result.addDbField(pathPart.getName(), pathPart.getName());
                }
            }
            return true;
        }

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

        public boolean visitToOne(ToOneProperty property) {
            DbRelationship dbRel = property.getRelationship().getDbRelationships().get(0);
            List<DbJoin> joins = dbRel.getJoins();
            for (DbJoin join : joins) {
                if (!join.getSource().isPrimaryKey()) {
                    result.addDbField(join.getSource().getName(), join.getSource().getName());
                }
            }
            return true;
        }
    };
    ObjEntity oe = resolver.getObjEntity(column.getType());
    DbEntity table = oe.getDbEntity();
    // Additionally collect PKs
    for (DbAttribute dba : table.getPrimaryKeys()) {
        result.addDbField(dba.getName(), dba.getName());
    }
    ClassDescriptor descriptor = resolver.getClassDescriptor(oe.getName());
    descriptor.visitAllProperties(visitor);
    // Collection columns for joint prefetch
    if (query.getPrefetchTree() != null) {
        for (PrefetchTreeNode prefetch : query.getPrefetchTree().adjacentJointNodes()) {
            // for each prefetch add columns from the target entity
            Expression prefetchExp = ExpressionFactory.exp(prefetch.getPath());
            ASTDbPath dbPrefetch = (ASTDbPath) oe.translateToDbPath(prefetchExp);
            DbRelationship r = findRelationByPath(table, dbPrefetch);
            if (r == null) {
                throw new CayenneRuntimeException("Invalid joint prefetch '%s' for entity: %s", prefetch, oe.getName());
            }
            // go via target OE to make sure that Java types are mapped correctly...
            ObjRelationship targetRel = (ObjRelationship) prefetchExp.evaluate(oe);
            ObjEntity targetEntity = targetRel.getTargetEntity();
            prefetch.setEntityName(targetRel.getSourceEntity().getName());
            String labelPrefix = dbPrefetch.getPath();
            Set<String> seenNames = new HashSet<>();
            for (ObjAttribute oa : targetEntity.getAttributes()) {
                Iterator<CayenneMapEntry> dbPathIterator = oa.getDbPathIterator();
                while (dbPathIterator.hasNext()) {
                    Object pathPart = dbPathIterator.next();
                    if (pathPart instanceof DbAttribute) {
                        DbAttribute attribute = (DbAttribute) pathPart;
                        if (seenNames.add(attribute.getName())) {
                            result.addDbField(labelPrefix + '.' + attribute.getName(), labelPrefix + '.' + attribute.getName());
                        }
                    }
                }
            }
            // append remaining target attributes such as keys
            DbEntity targetDbEntity = r.getTargetEntity();
            for (DbAttribute attribute : targetDbEntity.getAttributes()) {
                if (seenNames.add(attribute.getName())) {
                    result.addDbField(labelPrefix + '.' + attribute.getName(), labelPrefix + '.' + attribute.getName());
                }
            }
        }
    }
    return result;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ObjAttribute(org.apache.cayenne.map.ObjAttribute) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ASTDbPath(org.apache.cayenne.exp.parser.ASTDbPath) DbAttribute(org.apache.cayenne.map.DbAttribute) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) EntityResult(org.apache.cayenne.map.EntityResult) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty) CayenneMapEntry(org.apache.cayenne.util.CayenneMapEntry) ObjEntity(org.apache.cayenne.map.ObjEntity) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) DbEntity(org.apache.cayenne.map.DbEntity) Expression(org.apache.cayenne.exp.Expression) DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor) HashSet(java.util.HashSet)

Example 47 with ObjAttribute

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

the class PersistentDescriptor method indexAddedProperty.

void indexAddedProperty(PropertyDescriptor property) {
    if (property instanceof AttributeProperty) {
        AttributeProperty attributeProperty = (AttributeProperty) property;
        ObjAttribute attribute = attributeProperty.getAttribute();
        if (attribute.isPrimaryKey()) {
            if (idProperties == null) {
                idProperties = new ArrayList<>(2);
            }
            idProperties.add(attributeProperty);
        }
    } else if (property instanceof ArcProperty) {
        ObjRelationship relationship = ((ArcProperty) property).getRelationship();
        ObjRelationship reverseRelationship = relationship.getReverseRelationship();
        if (reverseRelationship != null && "java.util.Map".equals(reverseRelationship.getCollectionType())) {
            if (mapArcProperties == null) {
                mapArcProperties = new ArrayList<>(2);
            }
            mapArcProperties.add((ArcProperty) property);
        }
    }
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ObjAttribute(org.apache.cayenne.map.ObjAttribute) ArrayList(java.util.ArrayList)

Example 48 with ObjAttribute

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

the class PersistentDescriptorFactory method indexQualifiers.

protected void indexQualifiers(final PersistentDescriptor descriptor, EntityInheritanceTree inheritanceTree) {
    Expression qualifier;
    if (inheritanceTree != null) {
        qualifier = inheritanceTree.qualifierForEntityAndSubclasses();
    } else {
        qualifier = descriptor.getEntity().getDeclaredQualifier();
    }
    if (qualifier != null) {
        // using map instead of a Set to collect attributes, as
        // ObjEntity.getAttribute may return a decorator for attribute on
        // each call, resulting in dupes
        final Map<String, ObjAttribute> attributes = new HashMap<>();
        final DbEntity dbEntity = descriptor.getEntity().getDbEntity();
        qualifier.traverse(new TraversalHelper() {

            @Override
            public void startNode(Expression node, Expression parentNode) {
                if (node.getType() == Expression.DB_PATH) {
                    String path = node.getOperand(0).toString();
                    final DbAttribute attribute = dbEntity.getAttribute(path);
                    if (attribute != null) {
                        ObjAttribute objectAttribute = descriptor.getEntity().getAttributeForDbAttribute(attribute);
                        if (objectAttribute == null) {
                            objectAttribute = new ObjAttribute(attribute.getName()) {

                                @Override
                                public DbAttribute getDbAttribute() {
                                    return attribute;
                                }
                            };
                            // we semi-officially DO NOT support inheritance
                            // descriptors based on related entities, so
                            // here we
                            // assume that DbAttribute is rooted in the root
                            // DbEntity, and no relationship is involved.
                            objectAttribute.setDbAttributePath(attribute.getName());
                            objectAttribute.setType(TypesMapping.getJavaBySqlType(attribute.getType()));
                        }
                        attributes.put(objectAttribute.getName(), objectAttribute);
                    }
                } else if (node.getType() == Expression.OBJ_PATH) {
                    String path = node.getOperand(0).toString();
                    ObjAttribute attribute = descriptor.getEntity().getAttribute(path);
                    attributes.put(path, attribute);
                }
            }
        });
        descriptor.setDiscriminatorColumns(attributes.values());
        descriptor.setEntityQualifier(qualifier);
    }
}
Also used : ObjAttribute(org.apache.cayenne.map.ObjAttribute) DbEntity(org.apache.cayenne.map.DbEntity) Expression(org.apache.cayenne.exp.Expression) HashMap(java.util.HashMap) TraversalHelper(org.apache.cayenne.exp.TraversalHelper) DbAttribute(org.apache.cayenne.map.DbAttribute)

Example 49 with ObjAttribute

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

the class PersistentDescriptorTest method testCopyObjectProperties.

@Test
public void testCopyObjectProperties() {
    PersistentDescriptor d1 = new PersistentDescriptor();
    ObjAttribute attribute = mock(ObjAttribute.class);
    FieldAccessor accessor = new FieldAccessor(TstBean.class, "string", String.class);
    PropertyDescriptor property = new SimpleAttributeProperty(d1, accessor, attribute);
    d1.addDeclaredProperty(property);
    TstBean from = new TstBean();
    from.setString("123");
    TstBean to = new TstBean();
    d1.shallowMerge(from, to);
    assertEquals("123", to.getString());
}
Also used : ObjAttribute(org.apache.cayenne.map.ObjAttribute) TstBean(org.apache.cayenne.unit.util.TstBean) Test(org.junit.Test)

Example 50 with ObjAttribute

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

the class DataObjectAttributePropertyTest method testSerialization.

@Test
public void testSerialization() throws Exception {
    ObjEntity e1 = new ObjEntity("objEntityName");
    ObjAttribute a1 = new ObjAttribute("aName", "aType", e1);
    DataObjectAttributeProperty p1 = new DataObjectAttributeProperty(a1);
    DataObjectAttributeProperty p2 = Util.cloneViaSerialization(p1);
    assertNotNull(p2);
    assertNotNull(p2.getAttribute());
    assertEquals(p1.getAttribute().getName(), p2.getAttribute().getName());
    assertEquals(p1.getName(), p2.getName());
}
Also used : ObjEntity(org.apache.cayenne.map.ObjEntity) ObjAttribute(org.apache.cayenne.map.ObjAttribute) Test(org.junit.Test)

Aggregations

ObjAttribute (org.apache.cayenne.map.ObjAttribute)81 ObjEntity (org.apache.cayenne.map.ObjEntity)57 DbAttribute (org.apache.cayenne.map.DbAttribute)31 ObjRelationship (org.apache.cayenne.map.ObjRelationship)27 DbEntity (org.apache.cayenne.map.DbEntity)26 Test (org.junit.Test)26 DbRelationship (org.apache.cayenne.map.DbRelationship)19 DbJoin (org.apache.cayenne.map.DbJoin)12 DataMap (org.apache.cayenne.map.DataMap)9 ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)9 HashMap (java.util.HashMap)8 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)8 AttributeProperty (org.apache.cayenne.reflect.AttributeProperty)8 PropertyVisitor (org.apache.cayenne.reflect.PropertyVisitor)8 ToManyProperty (org.apache.cayenne.reflect.ToManyProperty)8 ToOneProperty (org.apache.cayenne.reflect.ToOneProperty)8 ArrayList (java.util.ArrayList)7 DataChannelDescriptor (org.apache.cayenne.configuration.DataChannelDescriptor)7 HashSet (java.util.HashSet)6 Expression (org.apache.cayenne.exp.Expression)6