Project

General

Profile

Download (3.64 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
    @Override
46
    public void valueChange(ValueChangeEvent event) {
47

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

    
57
        if(onSettingReloadedEntity){
58
            // avoid potential loops caused by setValue() below
59
            return;
60
        }
61

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

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

    
91
}
(24-24/28)