Updating an object via Apache Cayenne

566 Views Asked by At

I've spent two hours with yo'll ole google and not having success.

I'm using Apache Maven with mysql and Java EE (with a Restlet front).

I'm trying to grab an object given it's ID attribute, then update it and save back to the database. I've seen this answer here but it isn't working!

I've also read the documentation here.

In order of data transversal I accept a JSON object, feed that into the constructor of my object, build the object, grab a new object (no relation to our JSON one), populate it given the id, combine the two objects and save back to the database.

Here is the code for updating the database:

ObjectContext context = DataContext.createDataContext();
ObjectId idObject = new ObjectId("Vessel", Vessel.ID_PK_COLUMN, id);
ObjectIdQuery query = new ObjectIdQuery(idObject, false, ObjectIdQuery.CACHE_REFRESH);
Vessel v = (Vessel) DataObjectUtils.objectForQuery(context, query); //<-- This is our current vessel in the database.
v.updateVessel(new Vessel(json)); //<-- this calls the method below
context.commitChanges();

public vessel(JSONObject json) - constructor of vessel being used

public Vessel(JSONObject json)
{
  Iterator<String> keysIterator = json.keySet().iterator();
  while (keysIterator.hasNext()) 
  {
    String key = keysIterator.next();
    this.values.put(key, json.get(key));
  }
}

vessel.update(Vessel v) - this is the update method I'm using

public void updateVessel(Vessel v)
{
  for (Map.Entry pairs : v.values.entrySet()) {
    if(pairs.getValue() != null)
    {
      //okay it's not null, lets validate
      Object o = pairs.getValue();
      if(o instanceof String || o instanceof Double || o instanceof Integer || o instanceof Float || o instanceof Boolean)
      {
        //okay the value is of valid type
        this.values.put(pairs.getKey().toString(), o);
      }
    }
  }
}

I realize the huge security risk of storing my variable using these loops. This speeds up my development time IMMENSELY however. I haven't tested what happens when you pass in a variable that actually isn't being used but I imagine it would just get saved. In any regard that is not my question so please don't bring that up here (message me!).

If I do v.setSomething("awesome") instead of calling v.update(...) then the code works as expected (first found in the answer mentioned above).

Any ideas anyone? Help is very, very, very much appreciated!

EDIT: (About 1 hr later)

I was able to get this working (so far, need to finish testing) by changing the vessel.update code from this.values.put(pairs.getKey().toString(), o); to this.writeProperty(pairs.getKey().toString(), o);

Will report again after testing...

1

There are 1 best solutions below

2
On

My edit above seems to have fixed the issue. I tried to find the sourcecode for CayenneDataObject with no success so I can only assume that this fixes the issue because writeProperty() does some other code than just update the map this.values.

Here is the working piece of code under vessel.update().

public void updateVessel(Vessel v)
{
  for (Map.Entry pairs : v.values.entrySet()) {
    if(pairs.getValue() != null)
    {
      //okay it's not null, lets validate
      Object o = pairs.getValue();
      if(o instanceof String || o instanceof Double || o instanceof Integer || o instanceof Float || o instanceof Boolean)
      {
        //okay the value is of valid type
        this.writeProperty(pairs.getKey().toString(), o);
      }
    }
  }
}