Project

General

Profile

Download (3.68 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.vaadin.event;
10

    
11
import com.vaadin.data.Property.ValueChangeEvent;
12
import com.vaadin.data.Property.ValueChangeListener;
13
import com.vaadin.ui.Field;
14

    
15
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
16
import eu.etaxonomy.cdm.model.ICdmCacher;
17
import eu.etaxonomy.cdm.model.common.CdmBase;
18
import eu.etaxonomy.cdm.vaadin.view.name.CachingPresenter;
19
import eu.etaxonomy.vaadin.component.EntitySupport;
20

    
21
/**
22
 * The <code>ToOneRelatedEntityReloader</code> helps avoiding <i>java.lang.IllegalStateException: Multiple representations of the same entity</i>
23
 * in Hibernate sessions.
24
 *
25
 *
26
 * @author a.kohlbecker
27
 * @since 19.10.2017
28
 *
29
 */
30
public class ToOneRelatedEntityReloader<CDM extends CdmBase> implements ValueChangeListener {
31

    
32
    private static final long serialVersionUID = -1141764783149024788L;
33

    
34
    Field<CDM>  toOneRelatedEntityField;
35

    
36
    CachingPresenter cachingPresenter;
37

    
38
    boolean onSettingReloadedEntity;
39

    
40
    public ToOneRelatedEntityReloader( Field<CDM> toOneRelatedEntityField, CachingPresenter entityCache){
41
        this.toOneRelatedEntityField = toOneRelatedEntityField;
42
        this.cachingPresenter = entityCache;
43
    }
44

    
45
    /**
46
     * {@inheritDoc}
47
     */
48
    @Override
49
    public void valueChange(ValueChangeEvent event) {
50

    
51
        // TODO during the view initialization this method is called twice with the same value.
52
        // for faster view initialization it might make sense to reduce this to only one call.
53
        // only one call should be sufficient since the same value object is use in both calls
54
        // whereas i observed that it is a hibnerate proxy during the first call,
55
        // the second time it is the de-proxied entity which was during the first call inside the proxy.
56
        // Since both cdm enties are the same object
57
        // a reduction to one call should not break anything, but at least one call during the initialization
58
        // is required!
59

    
60
        if(onSettingReloadedEntity){
61
            // avoid potential loops caused by setValue() below
62
            return;
63
        }
64

    
65
        @SuppressWarnings("unchecked")
66
        CDM value = (CDM)event.getProperty().getValue();
67
        if(value == null || !value.isPersited()) {
68
            return;
69
        }
70
        value = HibernateProxyHelper.deproxy(value);
71

    
72
        ICdmCacher cache = cachingPresenter.getCache();
73
        if(cache != null){
74
            CDM cachedEntity = cache.load(value);
75
            if(// pure object comparison is not reliable since the entity may have been changed
76
                cachedEntity.getId() == value.getId() && cachedEntity.getClass() == value.getClass()
77
                ){
78
                    onSettingReloadedEntity = true;
79
                    if(EntitySupport.class.isAssignableFrom(toOneRelatedEntityField.getClass())){
80
                        ((EntitySupport)toOneRelatedEntityField).replaceEntityValue(cachedEntity);
81
                    } else {
82
                        toOneRelatedEntityField.removeValueChangeListener(this);
83
                        toOneRelatedEntityField.setValue(null); // reset to trick equals check in vaadin
84
                        toOneRelatedEntityField.setValue(cachedEntity);
85
                        toOneRelatedEntityField.addValueChangeListener(this);
86
                    }
87
                    onSettingReloadedEntity = false;
88
            }
89
        } else {
90
            throw new RuntimeException("The cache must not be null. See loadBeanById() in AbstractCdmEditorPresenter");
91
        }
92
    }
93

    
94
}
(26-26/29)