-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Populate existing object #431
Comments
Something like this seems to work well for me. I might have missed something but so far, so good... /**
* updates @target object from the @json object. Only fields existing in @json are affected
* @param target
* @param json
* @throws Exception
*/
public static void update(Object target, JsonObject json) throws Exception {
Class<? > class1 = target.getClass();
Set<Entry<String, JsonElement>> entrySet = json.entrySet();
for (Entry<String, JsonElement> entry : entrySet) {
String key = entry.getKey();
Field field = class1.getField(key);
Type genType = field.getGenericType();
field.set(target,
gson.fromJson(entry.getValue(),genType));
}
} |
For the love of source do NOT use the snippet above as is. But yes - This is a much needed feature. Just came across a very unfortunate use case. |
Any update on this? |
Why this issue was closed? is this became a planned feature? is it rejected? |
You can implement this using InstanceCreators. final Foo existing;
InstanceCreator<Foo> creator = new InstanceCreator<Foo>() {
public Foo createInstance(Type type) { return existing; }
}
Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class, creator).create();
Foo value = gson.fromJson(jsonString, Foo.class);
// value should be same as existing |
I needed to update a managed JPA object with a JSON from the web service, this is the solution I've found (I needed to use the local instance of appConfig): AppConfiguration appConfig = AppConfigurationDAO.getInstance().read(Long.parseLong(req.params(":id")));
InstanceCreator<AppConfiguration> creator = new InstanceCreator<AppConfiguration>() {
private AppConfiguration appConfig;
public AppConfiguration createInstance(Type type) {
return appConfig;
}
public InstanceCreator<AppConfiguration> withValue(AppConfiguration appConfig) {
this.appConfig = appConfig;
return this;
}
}.withValue(appConfig);
Gson gson = new GsonBuilder().registerTypeAdapter(AppConfiguration.class, creator).create();
appConfig = gson.fromJson(req.body(), AppConfiguration.class);
return AppConfigurationDAO.getInstance().update(appConfig); I then stated to wonder: can't we have a import com.google.gson.InstanceCreator;
import java.lang.reflect.Type;
public class InstanceUpdater<T> implements InstanceCreator<T> {
private T object;
public T createInstance(Type type) {
return object;
}
public InstanceUpdater(T object) {
this.object = object;
}
} Then I can use with something like this: InstanceCreator<AppConfiguration> creator = new InstanceUpdater<AppConfiguration>(appConfig); But I'm not sure, I feel there may be a better way of doing this, and it would be amazing to have something inside Gson to manage this for me. |
Why this issue was closed? is this became a planned feature? is it rejected? |
@Robertiano At the moment there is a workaround as outlined above with InstanceCreator. |
Apparently i need this as well, InstanceCreator is a bad option as if i want to make an extendable class static creators will need to be overwritten since there is no inheritance for that. |
|
Would love to see this, too. |
I've been looking for this functionality for years. @inder123 said "We are still searching for an elegant proposal." |
For posterity, if this is ever addressed: Take into account nested reuse of existing objects at any level of the deserialization, not just the root object. Then you can see why InstanceCreator doesn't work. You would need to pass in the containing object (which itself went through the usual process to be obtained), perhaps the InstanceUpdater where it passes along the containing object as context mainly so it can choose to reuse the T hanging off of it and continue on. I have use cases (multiple) where I have all sorts of state like event handlers hanging off of important levels of a large tree of objects, and I want essentially all the unimportant "leaf fields" overwritten with incoming values but the important object scaffolding itself remains unchanged at all levels. This is one of those things that is pretty easy to imagine how to implement it inside Gson, but hard to impossible to do from the outside looking in. |
Original issue reported on code.google.com by
pacesysj...@gmail.com
on 8 Apr 2012 at 5:12The text was updated successfully, but these errors were encountered: