private Map<?, ?> toMap_AttchedObject_MultiStepPath(ObjectContext context, Persistent persistent) { Iterator<CayenneMapEntry> pathComponents = Cayenne.getObjEntity(persistent).getDbEntity() .resolvePathComponents(this); LinkedList<DbRelationship> reversedPathComponents = new LinkedList<>(); while (pathComponents.hasNext()) { CayenneMapEntry component = pathComponents.next(); if (component instanceof DbRelationship) { DbRelationship rel = (DbRelationship) component; DbRelationship reverseRelationship = rel.getReverseRelationship(); if (reverseRelationship == null) { reverseRelationship = rel.createReverseRelationship(); } reversedPathComponents.addFirst(reverseRelationship); } else { break; // an attribute can only occur at the end of the path } } DbEntity finalEntity = reversedPathComponents.get(0).getSourceEntity(); StringBuilder reversedPathStr = new StringBuilder(); for (int i = 0; i < reversedPathComponents.size(); i++) { reversedPathStr.append(reversedPathComponents.get(i).getName()); if (i < reversedPathComponents.size() - 1) { reversedPathStr.append('.'); } } return ObjectSelect.dbQuery(finalEntity.getName()) .where(ExpressionFactory.matchDbExp(reversedPathStr.toString(), persistent)).selectOne(context); }
/** * Create reverse DbRelationships that were not created so far, since Cayenne requires * them. * * @since 1.0.5 */ protected void makeReverseDbRelationships(DbEntity dbEntity) { if (dbEntity == null) { throw new NullPointerException( "Attempt to create reverse relationships for the null DbEntity."); } // iterate over a copy of the collection, since in case of // reflexive relationships, we may modify source entity relationship map Collection clone = new ArrayList(dbEntity.getRelationships()); Iterator it = clone.iterator(); while (it.hasNext()) { DbRelationship relationship = (DbRelationship) it.next(); if (relationship.getReverseRelationship() == null) { DbRelationship reverse = relationship.createReverseRelationship(); String name = NamedObjectFactory.createName(DbRelationship.class, reverse .getSourceEntity(), relationship.getName() + "Reverse"); reverse.setName(name); relationship.getTargetEntity().addRelationship(reverse); } } }
/** * Create reverse DbRelationships that were not created so far, since * Cayenne requires them. * * @since 1.0.5 */ protected void makeReverseDbRelationships(DbEntity dbEntity) { if (dbEntity == null) { throw new NullPointerException("Attempt to create reverse relationships for the null DbEntity."); } // iterate over a copy of the collection, since in case of // reflexive relationships, we may modify source entity relationship map for (DbRelationship relationship : new ArrayList<>(dbEntity.getRelationships())) { if (relationship.getReverseRelationship() == null) { DbRelationship reverse = relationship.createReverseRelationship(); reverse.setName(NameBuilder.builder(reverse, reverse.getSourceEntity()) // TODO: we can do better with ObjectNameGenerator .baseName(relationship.getName() + "Reverse") .name()); relationship.getTargetEntity().addRelationship(reverse); } } }
/** * Updates missing mapping artifacts that can be guessed from other mapping * information. This implementation creates missing reverse relationships, * marking newly created relationships as "runtime". * * @since 3.0 */ public void applyDBLayerDefaults() { // connect DB layer for (DataMap map : getDataMaps()) { for (DbEntity entity : map.getDbEntities()) { // iterate by copy to avoid concurrency modification errors on // reflexive relationships DbRelationship[] relationships = entity.getRelationships().toArray( new DbRelationship[entity.getRelationships().size()]); for (DbRelationship relationship : relationships) { if (relationship.getReverseRelationship() == null) { DbRelationship reverse = relationship.createReverseRelationship(); Entity targetEntity = reverse.getSourceEntity(); reverse.setName(getUniqueRelationshipName(targetEntity)); reverse.setRuntime(true); targetEntity.addRelationship(reverse); logger.info("added runtime complimentary DbRelationship from " + targetEntity.getName() + " to " + reverse.getTargetEntityName()); } } } } }