Project

General

Profile

« Previous | Next » 

Revision 2c2bbc38

Added by Andreas Kohlbecker almost 7 years ago

ref #6707 1st attempt to make editing transient properties possible - save fails with LIE

View differences:

src/main/java/eu/etaxonomy/cdm/vaadin/view/name/TaxonNameEditorPresenter.java
8 8
*/
9 9
package eu.etaxonomy.cdm.vaadin.view.name;
10 10

  
11
import java.util.List;
12
import java.util.Set;
13

  
14
import org.apache.log4j.Logger;
15

  
11 16
import eu.etaxonomy.cdm.api.service.DeleteResult;
12 17
import eu.etaxonomy.cdm.api.service.config.NameDeletionConfigurator;
13 18
import eu.etaxonomy.cdm.model.name.TaxonName;
......
25 30

  
26 31
    private static final long serialVersionUID = -3538980627079389221L;
27 32

  
33
    private static final Logger logger = Logger.getLogger(TaxonNameEditorPresenter.class);
34

  
28 35
    /**
29 36
     * {@inheritDoc}
30 37
     */
......
52 59
        return getRepo().getNameService().delete(bean.getUuid(), config);
53 60
    }
54 61

  
62
    @Override
63
    protected TaxonName handleTransientProperties(TaxonName bean) {
64
        logger.trace(this._toString() + ".onEditorSaveEvent - handling transient properties");
65
        List<TaxonName> newBasionymNames = getView().getBasionymCombobox().getValueFromNestedFields();
66
        Set<TaxonName> oldBasionyms = bean.getBasionyms();
67
        boolean updateBasionyms = false;
68
        for(TaxonName newB : newBasionymNames){
69
            updateBasionyms = updateBasionyms || !oldBasionyms.contains(newB);
70
        }
71
        for(TaxonName oldB : oldBasionyms){
72
            updateBasionyms = updateBasionyms || !newBasionymNames.contains(oldB);
73
        }
74
        if(updateBasionyms){
75
            bean.removeBasionyms();
76
            for(TaxonName basionymName :newBasionymNames){
77
                getSession().merge(basionymName);
78
                bean.addBasionym(basionymName);
79
            }
80
        }
81
        return bean;
82

  
83
    }
84

  
55 85

  
56 86
}
src/main/java/eu/etaxonomy/vaadin/component/ToManyRelatedEntitiesComboboxSelect.java
75 75
        this.captionGenerator = captionGenerator;
76 76
    }
77 77

  
78

  
78 79
    /**
79 80
     * {@inheritDoc}
80 81
     */
src/main/java/eu/etaxonomy/vaadin/component/ToManyRelatedEntitiesListSelect.java
8 8
*/
9 9
package eu.etaxonomy.vaadin.component;
10 10

  
11
import java.util.ArrayList;
12
import java.util.HashSet;
11 13
import java.util.List;
14
import java.util.Set;
12 15

  
13 16
import org.apache.log4j.Logger;
14 17

  
18
import com.vaadin.data.Validator.InvalidValueException;
15 19
import com.vaadin.data.fieldgroup.FieldGroup;
16 20
import com.vaadin.data.util.BeanItemContainer;
17 21
import com.vaadin.server.FontAwesome;
......
23 27
import com.vaadin.ui.GridLayout;
24 28
import com.vaadin.ui.themes.ValoTheme;
25 29

  
30
import eu.etaxonomy.vaadin.mvp.AbstractCdmEditorPresenter;
31

  
26 32
/**
27 33
 * @author a.kohlbecker
28 34
 * @since May 11, 2017
......
56 62

  
57 63
    private GridLayout grid = new GridLayout(GRID_COLS,1);
58 64

  
65
    private Set<F> nestedFields = new HashSet<>() ;
66

  
59 67
    public  ToManyRelatedEntitiesListSelect(Class<V> itemType, Class<F> fieldType, String caption){
60 68
        this.fieldType = fieldType;
61 69
        this.itemType = itemType;
......
168 176
    protected int addNewRow(int row, V val) {
169 177
        try {
170 178
            F field = newFieldInstance(val);
179
            nestedFields .add(field);
171 180
            addStyledComponent(field);
172 181
            grid.addComponent(field, 0, row);
173 182
            grid.addComponent(buttonGroup(field), 1, row);
......
240 249
        parentFieldGroup = parent;
241 250
    }
242 251

  
252
    /**
253
     * {@inheritDoc}
254
     */
255
    @Override
256
    public void commit() throws SourceException, InvalidValueException {
257
        nestedFields.forEach(f -> f.commit());
258
        // calling super.commit() is useless if operating on a transient property!!
259
        super.commit();
260
    }
261

  
262
    /**
263
     * Obtains the List of values directly from the nested fields and ignores the
264
     * value of the <code>propertyDataSource</code>. This is useful when the ToManyRelatedEntitiesListSelect
265
     * is operating on a transient field, in which case the property is considered being read only by vaadin
266
     * so that the commit is doing nothing.
267
     *
268
     * See also {@link AbstractCdmEditorPresenter#handleTransientProperties(DTO bean)}
269
     *
270
     * @return
271
     */
272
    public List<V> getValueFromNestedFields() {
273
        List<V> nestedValues = new ArrayList<>();
274
        nestedFields.forEach(f -> nestedValues.add(f.getValue()));
275
        return nestedValues;
276
    }
277

  
243 278
    /**
244 279
     * {@inheritDoc}
245 280
     */
src/main/java/eu/etaxonomy/vaadin/mvp/AbstractCdmEditorPresenter.java
44 44
        logger.trace(this._toString() + " constructor");
45 45
    }
46 46

  
47
    @Override
48
    @EventListener // the generic type parameter <DTO> must not be used here otherwise events will not be received
49
    public void onEditorPreSaveEvent(EditorPreSaveEvent preSaveEvent){
50
        if(!isFromOwnView(preSaveEvent)){
51
            return;
52
        }
53

  
54
        logger.trace(this._toString() + ".onEditorPreSaveEvent - starting transaction");
55
        tx = startTransaction();
56
        // merge the bean and update the fieldGroup with the merged bean, so that updating
57
        // of field values in turn of the commit are can not cause LazyInitializationExeptions
58
        // the bean still has the original values at this point
59
        logger.trace(this._toString() + ".onEditorPreSaveEvent - merging bean into session");
60
        mergedBean((DTO) preSaveEvent.getBean());
61
    }
62

  
63 47
    /**
64 48
     * @return
65 49
     *
......
79 63
        return getRepo().startTransaction(true);
80 64
    }
81 65

  
66
    @SuppressWarnings("unchecked")
67
    @Override
68
    @EventListener // the generic type parameter <DTO> must not be used here otherwise events will not be received
69
    public void onEditorPreSaveEvent(EditorPreSaveEvent preSaveEvent){
70
        if(!isFromOwnView(preSaveEvent)){
71
            return;
72
        }
73

  
74
        logger.trace(this._toString() + ".onEditorPreSaveEvent - starting transaction");
75
        tx = startTransaction();
76
        // merge the bean and update the fieldGroup with the merged bean, so that updating
77
        // of field values in turn of the commit are can not cause LazyInitializationExeptions
78
        // the bean still has the original values at this point
79
        logger.trace(this._toString() + ".onEditorPreSaveEvent - merging bean into session");
80
        mergedBean((DTO) preSaveEvent.getBean());
81
    }
82

  
83
    @SuppressWarnings("unchecked")
82 84
    @Override
83 85
    @EventListener // the generic type parameter <DTO> must not be used here otherwise events will not be received
84 86
    public void onEditorSaveEvent(EditorSaveEvent saveEvent){
......
88 90
        // the bean is now updated with the changes made by the user
89 91
        Session session = getSession();
90 92
        logger.trace(this._toString() + ".onEditorSaveEvent - merging bean into session");
91
        // merge the changes into the session, ...
92
        DTO bean = mergedBean((DTO) saveEvent.getBean());
93

  
93
        DTO bean = (DTO) saveEvent.getBean();
94 94
        Type changeEventType;
95 95
        if(bean.getId() > 1){
96 96
            changeEventType = Type.MODIFIED;
97 97
        } else {
98 98
            changeEventType = Type.CREATED;
99 99
        }
100
        getRepo().getCommonService().saveOrUpdate(bean);
100
        bean = handleTransientProperties(bean);
101
        // merge the changes into the session, ...
102
        DTO mergedBean = mergedBean(bean);
103
        getRepo().getCommonService().saveOrUpdate(mergedBean);
101 104
        session.flush();
102 105
        logger.trace(this._toString() + ".onEditorSaveEvent - session flushed");
103 106
        getRepo().commitTransaction(tx);
......
106 109
            session.close();
107 110
        }
108 111
        logger.trace(this._toString() + ".onEditorSaveEvent - transaction comitted");
109
        eventBus.publishEvent(new EntityChangeEvent(bean.getClass(), bean.getId(), changeEventType));
112
        eventBus.publishEvent(new EntityChangeEvent(mergedBean.getClass(), mergedBean.getId(), changeEventType));
113
    }
114

  
115
    /**
116
     * EditorPresneters for beans with transient properties should overwrite this method to
117
     * update the beanItem with the changes made to the transient properties.
118
     * <p>
119
     * This is necessary because Vaadin MethodProperties are readonly when no setter is
120
     * available. This can be the case with transient properties. Automatic updating
121
     * of the property during the fieldGroup commit does not work in this case.
122
     */
123
    protected DTO handleTransientProperties(DTO bean) {
124
        // no need to handle transient properties in the generic case
125
        return bean;
110 126
    }
111 127

  
112 128
    /**

Also available in: Unified diff