Search in sources :

Example 31 with DbJoin

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

the class DbRelationshipValidator method getJoins.

private String getJoins(DbRelationship relationship) {
    List<String> joins = new ArrayList<>();
    for (DbJoin join : relationship.getJoins()) {
        joins.add("[source=" + join.getSourceName() + ",target=" + join.getTargetName() + "]");
    }
    Collections.sort(joins);
    return Util.join(joins, ",");
}
Also used : ArrayList(java.util.ArrayList) DbJoin(org.apache.cayenne.map.DbJoin)

Example 32 with DbJoin

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

the class ObjRelationshipValidator method validate.

void validate(ObjRelationship relationship, ValidationResult validationResult) {
    if (Util.isEmptyString(relationship.getName())) {
        addFailure(validationResult, relationship, "Unnamed ObjRelationship");
    } else if (relationship.getSourceEntity().getAttribute(relationship.getName()) != null) {
        // check if there are attributes having the same name
        addFailure(validationResult, relationship, "ObjRelationship '%s' has the same name as one of ObjAttributes", toString(relationship));
    } else {
        NameValidationHelper helper = NameValidationHelper.getInstance();
        String invalidChars = helper.invalidCharsInObjPathComponent(relationship.getName());
        if (invalidChars != null) {
            addFailure(validationResult, relationship, "ObjRelationship name '%s' contains invalid characters: %s", toString(relationship), invalidChars);
        } else if (helper.invalidDataObjectProperty(relationship.getName())) {
            addFailure(validationResult, relationship, "ObjRelationship name '%s' is a reserved word", toString(relationship));
        }
    }
    if (relationship.getTargetEntity() == null) {
        addFailure(validationResult, relationship, "ObjRelationship '%s' has no target entity", toString(relationship));
    } else {
        // check for missing DbRelationship mappings
        List<DbRelationship> dbRels = relationship.getDbRelationships();
        if (dbRels.isEmpty()) {
            addFailure(validationResult, relationship, "ObjRelationship '%s' has no DbRelationship mapping", toString(relationship));
        } else {
            DbEntity expectedSrc = relationship.getSourceEntity().getDbEntity();
            DbEntity expectedTarget = relationship.getTargetEntity().getDbEntity();
            if ((dbRels.get(0)).getSourceEntity() != expectedSrc || (dbRels.get(dbRels.size() - 1)).getTargetEntity() != expectedTarget) {
                addFailure(validationResult, relationship, "ObjRelationship '%s' has incomplete DbRelationship mapping", toString(relationship));
            }
        }
    }
    // foreign key attributes are mandatory.
    if (relationship.isToMany() && !relationship.isFlattened() && (relationship.getDeleteRule() == DeleteRule.NULLIFY)) {
        ObjRelationship inverse = relationship.getReverseRelationship();
        if (inverse != null) {
            DbRelationship firstRel = inverse.getDbRelationships().get(0);
            Iterator<DbJoin> attributePairIterator = firstRel.getJoins().iterator();
            // by default, the relation will be check for mandatory.
            boolean check = true;
            while (attributePairIterator.hasNext()) {
                DbJoin pair = attributePairIterator.next();
                if (!pair.getSource().isMandatory()) {
                    // a field of the fk can be nullable, cancel the check.
                    check = false;
                    break;
                }
            }
            if (check) {
                addFailure(validationResult, relationship, "ObjRelationship '%s' has a Nullify delete rule and a mandatory reverse relationship", toString(relationship));
            }
        }
    }
    // check for relationships with same source and target entities
    ObjEntity entity = relationship.getSourceEntity();
    for (ObjRelationship rel : entity.getRelationships()) {
        if (relationship.getDbRelationshipPath() != null && relationship.getDbRelationshipPath().equals(rel.getDbRelationshipPath())) {
            if (relationship != rel && relationship.getTargetEntity() == rel.getTargetEntity() && relationship.getSourceEntity() == rel.getSourceEntity()) {
                addFailure(validationResult, relationship, "ObjectRelationship '%s' duplicates relationship '%s'", toString(relationship), toString(rel));
            }
        }
    }
    // check for invalid relationships in inherited entities
    if (relationship.getReverseRelationship() != null) {
        ObjRelationship revRel = relationship.getReverseRelationship();
        if (relationship.getSourceEntity() != revRel.getTargetEntity() || relationship.getTargetEntity() != revRel.getSourceEntity()) {
            addFailure(validationResult, revRel, "Usage of super entity's relationships '%s' as reversed relationships for sub entity is discouraged", toString(revRel));
        }
    }
    checkForDuplicates(relationship, validationResult);
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ObjEntity(org.apache.cayenne.map.ObjEntity) DbEntity(org.apache.cayenne.map.DbEntity) DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin)

Example 33 with DbJoin

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

the class AshwoodEntitySorter method doIndexSorter.

/**
 * Reindexes internal sorter without synchronization.
 */
protected void doIndexSorter() {
    Map<DbEntity, List<DbRelationship>> reflexiveDbEntities = new HashMap<>();
    Digraph<DbEntity, List<DbAttribute>> referentialDigraph = new MapDigraph<>();
    if (entityResolver != null) {
        for (DbEntity entity : entityResolver.getDbEntities()) {
            referentialDigraph.addVertex(entity);
        }
    }
    for (DbEntity destination : entityResolver.getDbEntities()) {
        for (DbRelationship candidate : destination.getRelationships()) {
            if ((!candidate.isToMany() && !candidate.isToDependentPK()) || candidate.isToMasterPK()) {
                DbEntity origin = candidate.getTargetEntity();
                boolean newReflexive = destination.equals(origin);
                for (DbJoin join : candidate.getJoins()) {
                    DbAttribute targetAttribute = join.getTarget();
                    if (targetAttribute.isPrimaryKey()) {
                        if (newReflexive) {
                            List<DbRelationship> reflexiveRels = reflexiveDbEntities.get(destination);
                            if (reflexiveRels == null) {
                                reflexiveRels = new ArrayList<>(1);
                                reflexiveDbEntities.put(destination, reflexiveRels);
                            }
                            reflexiveRels.add(candidate);
                            newReflexive = false;
                        }
                        List<DbAttribute> fks = referentialDigraph.getArc(origin, destination);
                        if (fks == null) {
                            fks = new ArrayList<>();
                            referentialDigraph.putArc(origin, destination, fks);
                        }
                        fks.add(targetAttribute);
                    }
                }
            }
        }
    }
    StrongConnection<DbEntity, List<DbAttribute>> contractor = new StrongConnection<>(referentialDigraph);
    Digraph<Collection<DbEntity>, Collection<List<DbAttribute>>> contractedReferentialDigraph = new MapDigraph<>();
    contractor.contract(contractedReferentialDigraph);
    IndegreeTopologicalSort<Collection<DbEntity>> sorter = new IndegreeTopologicalSort<>(contractedReferentialDigraph);
    Map<DbEntity, ComponentRecord> components = new HashMap<>(contractedReferentialDigraph.order());
    int componentIndex = 0;
    while (sorter.hasNext()) {
        Collection<DbEntity> component = sorter.next();
        ComponentRecord rec = new ComponentRecord(componentIndex++, component);
        for (DbEntity table : component) {
            components.put(table, rec);
        }
    }
    this.reflexiveDbEntities = reflexiveDbEntities;
    this.components = components;
}
Also used : HashMap(java.util.HashMap) DbAttribute(org.apache.cayenne.map.DbAttribute) StrongConnection(org.apache.cayenne.ashwood.graph.StrongConnection) IndegreeTopologicalSort(org.apache.cayenne.ashwood.graph.IndegreeTopologicalSort) MapDigraph(org.apache.cayenne.ashwood.graph.MapDigraph) DbEntity(org.apache.cayenne.map.DbEntity) DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin) Collection(java.util.Collection) ArrayList(java.util.ArrayList) List(java.util.List)

Example 34 with DbJoin

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

the class DbRelationshipHandler method createDbAttributePair.

private void createDbAttributePair(Attributes attributes) {
    DbJoin join = new DbJoin(dbRelationship);
    join.setSourceName(attributes.getValue("source"));
    join.setTargetName(attributes.getValue("target"));
    dbRelationship.addJoin(join);
}
Also used : DbJoin(org.apache.cayenne.map.DbJoin)

Example 35 with DbJoin

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

the class JdbcAdapter method createFkConstraint.

/**
 * Returns a SQL string that can be used to create a foreign key constraint
 * for the relationship.
 */
@Override
public String createFkConstraint(DbRelationship rel) {
    DbEntity source = rel.getSourceEntity();
    StringBuilder buf = new StringBuilder();
    StringBuilder refBuf = new StringBuilder();
    buf.append("ALTER TABLE ");
    buf.append(quotingStrategy.quotedFullyQualifiedName(source));
    buf.append(" ADD FOREIGN KEY (");
    boolean first = true;
    for (DbJoin join : rel.getJoins()) {
        if (first) {
            first = false;
        } else {
            buf.append(", ");
            refBuf.append(", ");
        }
        buf.append(quotingStrategy.quotedSourceName(join));
        refBuf.append(quotingStrategy.quotedTargetName(join));
    }
    buf.append(") REFERENCES ");
    buf.append(quotingStrategy.quotedFullyQualifiedName(rel.getTargetEntity()));
    buf.append(" (").append(refBuf.toString()).append(')');
    return buf.toString();
}
Also used : DbEntity(org.apache.cayenne.map.DbEntity) DbJoin(org.apache.cayenne.map.DbJoin)

Aggregations

DbJoin (org.apache.cayenne.map.DbJoin)49 DbRelationship (org.apache.cayenne.map.DbRelationship)35 DbEntity (org.apache.cayenne.map.DbEntity)24 DbAttribute (org.apache.cayenne.map.DbAttribute)18 ObjRelationship (org.apache.cayenne.map.ObjRelationship)14 ObjAttribute (org.apache.cayenne.map.ObjAttribute)12 ObjEntity (org.apache.cayenne.map.ObjEntity)11 ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)9 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)8 ArrayList (java.util.ArrayList)7 AttributeProperty (org.apache.cayenne.reflect.AttributeProperty)7 PropertyVisitor (org.apache.cayenne.reflect.PropertyVisitor)7 ToManyProperty (org.apache.cayenne.reflect.ToManyProperty)7 ToOneProperty (org.apache.cayenne.reflect.ToOneProperty)7 HashMap (java.util.HashMap)6 Test (org.junit.Test)6 QuotingStrategy (org.apache.cayenne.dba.QuotingStrategy)5 EJBQLException (org.apache.cayenne.ejbql.EJBQLException)5 HashSet (java.util.HashSet)4 List (java.util.List)3