/** * Simule la présence d'une valeur. * * <p>Seules les relations toOne sont supportées. * * @param property La propriété à simuler. */ public void fake(String property) { // Test de la propriété ObjEntity ent = objEntity(); ObjRelationship rel = (ObjRelationship) ent.getRelationship(property); if (rel == null) { throw new IllegalArgumentException("Pas de relation " + ent.getName() + "." + property); } if (rel.isToMany()) { throw new IllegalArgumentException( "La relation " + ent.getName() + "." + property + " n'est pas un toOne"); } ObjEntity targetEntity = (ObjEntity) rel.getTargetEntity(); // Ok, ajout. fakes.put(property, targetEntity.getJavaClass()); }
/** * Creates a DataObject from DataRow. * * @see DataRow * @since 3.1 */ public <T extends Persistent> T objectFromDataRow(Class<T> objectClass, DataRow dataRow) { ObjEntity entity = this.getEntityResolver().getObjEntity(objectClass); if (entity == null) { throw new CayenneRuntimeException("Unmapped Java class: " + objectClass); } ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(entity.getName()); List<T> list = objectsFromDataRows(descriptor, Collections.singletonList(dataRow)); return list.get(0); }
/** * Creates and registers a new persistent object. * * @since 1.2 */ @Override public <T> T newObject(Class<T> persistentClass) { if (persistentClass == null) { throw new NullPointerException("Null 'persistentClass'"); } ObjEntity entity = getEntityResolver().getObjEntity(persistentClass); if (entity == null) { throw new IllegalArgumentException( "Class is not mapped with Cayenne: " + persistentClass.getName()); } return (T) newObject(entity.getName()); }
protected void indexSubclassDescriptors( PersistentDescriptor descriptor, EntityInheritanceTree inheritanceTree) { if (inheritanceTree != null) { for (EntityInheritanceTree child : inheritanceTree.getChildren()) { ObjEntity childEntity = child.getEntity(); descriptor.addSubclassDescriptor( childEntity.getClassName(), descriptorMap.getDescriptor(childEntity.getName())); indexSubclassDescriptors(descriptor, child); } } }
/** * Registers a transient object with the context, recursively registering all transient persistent * objects attached to this object via relationships. * * <p><i>Note that since 3.0 this method takes Object as an argument instead of a {@link * DataObject}.</i> * * @param object new object that needs to be made persistent. */ @Override public void registerNewObject(Object object) { if (object == null) { throw new NullPointerException("Can't register null object."); } ObjEntity entity = getEntityResolver().getObjEntity((Persistent) object); if (entity == null) { throw new IllegalArgumentException( "Can't find ObjEntity for Persistent class: " + object.getClass().getName() + ", class is likely not mapped."); } final Persistent persistent = (Persistent) object; // sanity check - maybe already registered if (persistent.getObjectId() != null) { if (persistent.getObjectContext() == this) { // already registered, just ignore return; } else if (persistent.getObjectContext() != null) { throw new IllegalStateException( "Persistent is already registered with another DataContext. " + "Try using 'localObjects()' instead."); } } else { persistent.setObjectId(new ObjectId(entity.getName())); } ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(entity.getName()); if (descriptor == null) { throw new IllegalArgumentException("Invalid entity name: " + entity.getName()); } injectInitialValue(object); // now we need to find all arc changes, inject missing value holders and // pull in // all transient connected objects descriptor.visitProperties( new PropertyVisitor() { public boolean visitToMany(ToManyProperty property) { property.injectValueHolder(persistent); if (!property.isFault(persistent)) { Object value = property.readProperty(persistent); Collection<Map.Entry> collection = (value instanceof Map) ? ((Map) value).entrySet() : (Collection) value; Iterator<Map.Entry> it = collection.iterator(); while (it.hasNext()) { Object target = it.next(); if (target instanceof Persistent) { Persistent targetDO = (Persistent) target; // make sure it is registered registerNewObject(targetDO); getObjectStore() .arcCreated( persistent.getObjectId(), targetDO.getObjectId(), property.getName()); } } } return true; } public boolean visitToOne(ToOneProperty property) { Object target = property.readPropertyDirectly(persistent); if (target instanceof Persistent) { Persistent targetDO = (Persistent) target; // make sure it is registered registerNewObject(targetDO); getObjectStore() .arcCreated(persistent.getObjectId(), targetDO.getObjectId(), property.getName()); } return true; } public boolean visitAttribute(AttributeProperty property) { return true; } }); }
/** * Returns a DataRow reflecting current, possibly uncommitted, object state. * * <p><strong>Warning:</strong> This method will return a partial snapshot if an object or one of * its related objects that propagate their keys to this object have temporary ids. DO NOT USE * this method if you expect a DataRow to represent a complete object state. * * @since 1.1 */ public DataRow currentSnapshot(final Persistent object) { // for a HOLLOW object return snapshot from cache if (object.getPersistenceState() == PersistenceState.HOLLOW && object.getObjectContext() != null) { return getObjectStore().getSnapshot(object.getObjectId()); } ObjEntity entity = getEntityResolver().getObjEntity(object); final ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(entity.getName()); final DataRow snapshot = new DataRow(10); snapshot.setEntityName(entity.getName()); descriptor.visitProperties( new PropertyVisitor() { public boolean visitAttribute(AttributeProperty property) { ObjAttribute objAttr = property.getAttribute(); // processing compound attributes correctly snapshot.put(objAttr.getDbAttributePath(), property.readPropertyDirectly(object)); return true; } public boolean visitToMany(ToManyProperty property) { // do nothing return true; } public boolean visitToOne(ToOneProperty property) { ObjRelationship rel = property.getRelationship(); // if target doesn't propagates its key value, skip it if (rel.isSourceIndependentFromTargetChange()) { return true; } Object targetObject = property.readPropertyDirectly(object); if (targetObject == null) { return true; } // if target is Fault, get id attributes from stored snapshot // to avoid unneeded fault triggering if (targetObject instanceof Fault) { DataRow storedSnapshot = getObjectStore().getSnapshot(object.getObjectId()); if (storedSnapshot == null) { throw new CayenneRuntimeException( "No matching objects found for ObjectId " + object.getObjectId() + ". Object may have been deleted externally."); } DbRelationship dbRel = rel.getDbRelationships().get(0); for (DbJoin join : dbRel.getJoins()) { String key = join.getSourceName(); snapshot.put(key, storedSnapshot.get(key)); } return true; } // target is resolved and we have an FK->PK to it, // so extract it from target... Persistent target = (Persistent) targetObject; Map<String, Object> idParts = target.getObjectId().getIdSnapshot(); // this may happen in uncommitted objects - see the warning in // the JavaDoc // of // this method. if (idParts.isEmpty()) { return true; } DbRelationship dbRel = rel.getDbRelationships().get(0); Map<String, Object> fk = dbRel.srcFkSnapshotWithTargetSnapshot(idParts); snapshot.putAll(fk); return true; } }); // process object id map // we should ignore any object id values if a corresponding attribute // is a part of relationship "toMasterPK", since those values have been // set above when db relationships where processed. Map<String, Object> thisIdParts = object.getObjectId().getIdSnapshot(); if (thisIdParts != null) { // put only those that do not exist in the map for (Map.Entry<String, Object> entry : thisIdParts.entrySet()) { String nextKey = entry.getKey(); if (!snapshot.containsKey(nextKey)) { snapshot.put(nextKey, entry.getValue()); } } } return snapshot; }
public void testForeignKey() throws Exception { dropTableIfPresent("NEW_TABLE"); dropTableIfPresent("NEW_TABLE2"); assertTokensAndExecute(0, 0); DbEntity dbEntity1 = new DbEntity("NEW_TABLE"); DbAttribute e1col1 = new DbAttribute("ID", Types.INTEGER, dbEntity1); e1col1.setMandatory(true); e1col1.setPrimaryKey(true); dbEntity1.addAttribute(e1col1); DbAttribute e1col2 = new DbAttribute("NAME", Types.VARCHAR, dbEntity1); e1col2.setMaxLength(10); e1col2.setMandatory(false); dbEntity1.addAttribute(e1col2); map.addDbEntity(dbEntity1); DbEntity dbEntity2 = new DbEntity("NEW_TABLE2"); DbAttribute e2col1 = new DbAttribute("ID", Types.INTEGER, dbEntity2); e2col1.setMandatory(true); e2col1.setPrimaryKey(true); dbEntity2.addAttribute(e2col1); DbAttribute e2col2 = new DbAttribute("FK", Types.INTEGER, dbEntity2); dbEntity2.addAttribute(e2col2); DbAttribute e2col3 = new DbAttribute("NAME", Types.VARCHAR, dbEntity2); e2col3.setMaxLength(10); dbEntity2.addAttribute(e2col3); map.addDbEntity(dbEntity2); // create db relationships DbRelationship rel1To2 = new DbRelationship("rel1To2"); rel1To2.setSourceEntity(dbEntity1); rel1To2.setTargetEntity(dbEntity2); rel1To2.setToMany(true); rel1To2.addJoin(new DbJoin(rel1To2, e1col1.getName(), e2col2.getName())); dbEntity1.addRelationship(rel1To2); DbRelationship rel2To1 = new DbRelationship("rel2To1"); rel2To1.setSourceEntity(dbEntity2); rel2To1.setTargetEntity(dbEntity1); rel2To1.setToMany(false); rel2To1.addJoin(new DbJoin(rel2To1, e2col2.getName(), e1col1.getName())); dbEntity2.addRelationship(rel2To1); assertSame(rel1To2, rel2To1.getReverseRelationship()); assertSame(rel2To1, rel1To2.getReverseRelationship()); assertTokensAndExecute(4, 0); assertTokensAndExecute(0, 0); // create ObjEntities ObjEntity objEntity1 = new ObjEntity("NewTable"); objEntity1.setDbEntity(dbEntity1); ObjAttribute oatr1 = new ObjAttribute("name"); oatr1.setDbAttributePath(e1col2.getName()); oatr1.setType("java.lang.String"); objEntity1.addAttribute(oatr1); map.addObjEntity(objEntity1); ObjEntity objEntity2 = new ObjEntity("NewTable2"); objEntity2.setDbEntity(dbEntity2); ObjAttribute o2a1 = new ObjAttribute("name"); o2a1.setDbAttributePath(e2col3.getName()); o2a1.setType("java.lang.String"); objEntity2.addAttribute(o2a1); map.addObjEntity(objEntity2); // create ObjRelationships assertEquals(0, objEntity1.getRelationships().size()); assertEquals(0, objEntity2.getRelationships().size()); ObjRelationship objRel1To2 = new ObjRelationship("objRel1To2"); objRel1To2.addDbRelationship(rel1To2); objRel1To2.setSourceEntity(objEntity1); objRel1To2.setTargetEntity(objEntity2); objEntity1.addRelationship(objRel1To2); ObjRelationship objRel2To1 = new ObjRelationship("objRel2To1"); objRel2To1.addDbRelationship(rel2To1); objRel2To1.setSourceEntity(objEntity2); objRel2To1.setTargetEntity(objEntity1); objEntity2.addRelationship(objRel2To1); assertEquals(1, objEntity1.getRelationships().size()); assertEquals(1, objEntity2.getRelationships().size()); assertSame(objRel1To2, objRel2To1.getReverseRelationship()); assertSame(objRel2To1, objRel1To2.getReverseRelationship()); // remove relationship and fk from model, merge to db and read to model dbEntity2.removeRelationship(rel2To1.getName()); dbEntity1.removeRelationship(rel1To2.getName()); dbEntity2.removeAttribute(e2col2.getName()); List<MergerToken> tokens = createMergeTokens(); assertTokens(tokens, 2, 1); for (MergerToken token : tokens) { if (token.getDirection().isToDb()) { execute(token); } } assertTokensAndExecute(0, 0); dbEntity2.addRelationship(rel2To1); dbEntity1.addRelationship(rel1To2); dbEntity2.addAttribute(e2col2); // try do use the merger to remove the relationship in the model tokens = createMergeTokens(); assertTokens(tokens, 2, 0); // TODO: reversing the following two tokens should also reverse the order MergerToken token0 = tokens.get(0).createReverse(mergerFactory()); MergerToken token1 = tokens.get(1).createReverse(mergerFactory()); if (!(token0 instanceof DropRelationshipToModel && token1 instanceof DropColumnToModel || token1 instanceof DropRelationshipToModel && token0 instanceof DropColumnToModel)) { fail(); } execute(token0); execute(token1); // check after merging assertNull(dbEntity2.getAttribute(e2col2.getName())); assertEquals(0, dbEntity1.getRelationships().size()); assertEquals(0, dbEntity2.getRelationships().size()); assertEquals(0, objEntity1.getRelationships().size()); assertEquals(0, objEntity2.getRelationships().size()); // clear up dbEntity1.removeRelationship(rel1To2.getName()); dbEntity2.removeRelationship(rel2To1.getName()); map.removeObjEntity(objEntity1.getName(), true); map.removeDbEntity(dbEntity1.getName(), true); map.removeObjEntity(objEntity2.getName(), true); map.removeDbEntity(dbEntity2.getName(), true); resolver.refreshMappingCache(); assertNull(map.getObjEntity(objEntity1.getName())); assertNull(map.getDbEntity(dbEntity1.getName())); assertNull(map.getObjEntity(objEntity2.getName())); assertNull(map.getDbEntity(dbEntity2.getName())); assertFalse(map.getDbEntities().contains(dbEntity1)); assertFalse(map.getDbEntities().contains(dbEntity2)); assertTokensAndExecute(2, 0); assertTokensAndExecute(0, 0); }