From 35e2a34c9c4dfcf9117db31f6403401129c9befc Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Mon, 14 Apr 2014 10:19:17 +0300 Subject: [PATCH] Fix FieldGroup and TransactionalPropertyWrapper memory leaks (#13438) Change-Id: Ifafb6d87b4280f8bd9e631235fff62f42de4b4c8 --- .../vaadin/data/fieldgroup/FieldGroup.java | 8 +++++- .../util/TransactionalPropertyWrapper.java | 26 ++++++++++++++----- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java index 23f2da53ce..c5f9907610 100644 --- a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java +++ b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java @@ -316,12 +316,18 @@ public class FieldGroup implements Serializable { "The given field is not part of this FieldBinder"); } + TransactionalPropertyWrapper wrapper = null; Property fieldDataSource = field.getPropertyDataSource(); if (fieldDataSource instanceof TransactionalPropertyWrapper) { - fieldDataSource = ((TransactionalPropertyWrapper) fieldDataSource) + wrapper = (TransactionalPropertyWrapper) fieldDataSource; + fieldDataSource = ((TransactionalPropertyWrapper) fieldDataSource) .getWrappedProperty(); + } if (fieldDataSource == getItemProperty(propertyId)) { + if (null != wrapper) { + wrapper.detachFromProperty(); + } field.setPropertyDataSource(null); } fieldToPropertyId.remove(field); diff --git a/server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java b/server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java index 6b0119c503..3bac5bdfb8 100644 --- a/server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java +++ b/server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java @@ -48,18 +48,32 @@ public class TransactionalPropertyWrapper extends AbstractProperty private boolean inTransaction = false; private boolean valueChangePending; private T valueBeforeTransaction; + private final ValueChangeListener listener = new ValueChangeListener() { + + @Override + public void valueChange(ValueChangeEvent event) { + fireValueChange(); + } + }; public TransactionalPropertyWrapper(Property wrappedProperty) { this.wrappedProperty = wrappedProperty; if (wrappedProperty instanceof ValueChangeNotifier) { ((ValueChangeNotifier) wrappedProperty) - .addListener(new ValueChangeListener() { + .addValueChangeListener(listener); + } + } - @Override - public void valueChange(ValueChangeEvent event) { - fireValueChange(); - } - }); + /** + * Removes the ValueChangeListener from wrapped Property that was added by + * TransactionalPropertyWrapper. + * + * @since 7.1.14 + */ + public void detachFromProperty() { + if (wrappedProperty instanceof ValueChangeNotifier) { + ((ValueChangeNotifier) wrappedProperty) + .removeValueChangeListener(listener); } } -- 2.39.5