GoodbyDao/src/main/java/ir/cafebabe/dao/impl/AbstractDao.java
@Override
  public void updateOne(E object, String... properties) {
    if (object.getId() == null) {
      throw new RuntimeException("Not a Persisted entity");
    }
    if (properties == null || properties.length == 0) {
      entityManager.merge(object);
      return;
    }

    // for performance reason its better to mix getting fields, their values
    // and making query all in one loop
    // in one iteration
    StringBuilder sb = new StringBuilder();
    sb.append("Update " + clazz.getName() + " SET ");

    // cache of fieldName --> value
    Map<String, Object> cache = new HashMap<String, Object>();

    for (String prop : properties) {
      try {
        Field field = object.getClass().getDeclaredField(prop);
        field.setAccessible(true);
        Object value = field.get(object);
        if (value instanceof Collection) {
          // value = new LinkedList<>((Collection< ? extends Object>) value);
          throw new RuntimeException("Collection property is not suppotred.");
        }
        cache.put(prop, value);

        // ignore first comma
        if (cache.size() > 1) {
          sb.append(" ,");
        }
        sb.append(prop);
        sb.append(" = :");
        sb.append(prop);

      } catch (Exception e) { // TODO: use fine grain exceptions
                              // FIX: NEXT RELEASE I hope :)
        throw new RuntimeException(e);
      }
    }

    // this means nothing will be updated so hitting db is unnecessary
    if (cache.size() == 0)
      return;

    sb.append(" WHERE id = " + object.getId());
    Query query = entityManager.createQuery(sb.toString());
    for (Entry<String, Object> entry : cache.entrySet()) {
      query.setParameter(entry.getKey(), entry.getValue());
    }
    query.executeUpdate();
  }
@Override
  public void updateOne(E object, String... properties) {
    if (object.getId() == null) {
      throw new RuntimeException("Not a Persisted entity");
    }
    if (properties == null || properties.length == 0) {
      entityManager.merge(object);
      return;
    }

    // for performance reason its better to mix getting fields, their values
    // and making query all in one loop
    // in one iteration
    StringBuilder sb = new StringBuilder();
    sb.append("Update " + clazz.getName() + " SET ");

    // cache of fieldName --> value
    Map<String, Object> cache = new HashMap<String, Object>();

    for (String prop : properties) {
      try {
        Field field = object.getClass().getDeclaredField(prop);
        field.setAccessible(true);
        Object value = field.get(object);
        if (value instanceof Collection) {
          // value = new LinkedList<>((Collection< ? extends Object>) value);
          throw new RuntimeException("Collection property is not suppotred.");
        }
        cache.put(prop, value);

        // ignore first comma
        if (cache.size() > 1) {
          sb.append(" ,");
        }
        sb.append(prop);
        sb.append(" = :");
        sb.append(prop);

      } catch (Exception e) { // TODO: use fine grain exceptions
                              // FIX: NEXT RELEASE I hope :)
        throw new RuntimeException(e);
      }
    }

    // this means nothing will be updated so hitting db is unnecessary
    if (cache.size() == 0)
      return;

    sb.append(" WHERE id = " + object.getId());
    Query query = entityManager.createQuery(sb.toString());
    for (Entry<String, Object> entry : cache.entrySet()) {
      query.setParameter(entry.getKey(), entry.getValue());
    }
    query.executeUpdate();
  }
Only update specified properties of the Object

@param object
An dirty object.
@param properties
array of property names. for now Collection properties in not
supported.