Esempio n. 1
0
  /**
   * Instantiates a new object and registers it with this context. Object class is determined from
   * the mapped entity. Object class must have a default constructor.
   *
   * <p><i>Note: in most cases {@link #newObject(Class)} method should be used, however this method
   * is helpful when generic persistent classes are used.</i>
   *
   * @since 3.0
   */
  public Persistent newObject(String entityName) {
    ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(entityName);
    if (descriptor == null) {
      throw new IllegalArgumentException("Invalid entity name: " + entityName);
    }

    Persistent object;
    try {
      object = (Persistent) descriptor.createObject();
    } catch (Exception ex) {
      throw new CayenneRuntimeException("Error instantiating object.", ex);
    }

    // this will initialize to-many lists
    descriptor.injectValueHolders(object);

    ObjectId id = new ObjectId(entityName);

    // note that the order of initialization of persistence artifacts below
    // is
    // important - do not change it lightly
    object.setObjectId(id);

    injectInitialValue(object);

    return object;
  }
Esempio n. 2
0
  /**
   * An internal version of {@link #localObject(Object)} that operates on ObjectId instead of
   * Persistent, and wouldn't attempt to look up an object in the parent channel.
   *
   * @since 3.1
   */
  Persistent findOrCreateObject(ObjectId id) {

    if (id == null) {
      throw new IllegalArgumentException("Null ObjectId");
    }

    // have to synchronize almost the entire method to prevent multiple
    // threads from
    // messing up dataobjects per CAY-845. Originally only parts of "else"
    // were
    // synchronized, but we had to expand the lock scope to ensure
    // consistent
    // behavior.
    synchronized (getGraphManager()) {
      Persistent cachedObject = (Persistent) getGraphManager().getNode(id);

      // return an existing object
      if (cachedObject != null) {

        int state = cachedObject.getPersistenceState();

        // TODO: Andrus, 1/24/2006 implement smart merge for modified
        // objects...
        if (state != PersistenceState.MODIFIED && state != PersistenceState.DELETED) {

          ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(id.getEntityName());

          descriptor.injectValueHolders(cachedObject);
        }

        return cachedObject;
      }

      // create and register a hollow object
      ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(id.getEntityName());
      Persistent localObject = (Persistent) descriptor.createObject();

      localObject.setObjectContext(this);
      localObject.setObjectId(id);

      getGraphManager().registerNode(id, localObject);
      localObject.setPersistenceState(PersistenceState.HOLLOW);

      return localObject;
    }
  }
Esempio n. 3
0
  /**
   * 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;
          }
        });
  }