Project

General

Profile

Download (3.42 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

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

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

    
33
    Field<CDM>  toOneRelatedEntityField;
34

    
35
    CachingPresenter cachingPresenter;
36

    
37
    boolean onSettingReloadedEntity;
38

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

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

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

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

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

    
71
        ICdmCacher cache = cachingPresenter.getCache();
72
        if(cache != null){
73
            CDM cachedEntity = (CDM) cache.load(value);
74
            // cachingPresenter.addRootEntity(cachedEntity);
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
                    toOneRelatedEntityField.removeValueChangeListener(this);
80
                    toOneRelatedEntityField.setValue(null); // reset to trick equals check in vaadin
81
                    toOneRelatedEntityField.setValue(cachedEntity);
82
                    toOneRelatedEntityField.addValueChangeListener(this);
83
                    onSettingReloadedEntity = false;
84
            }
85
        } else {
86
            throw new RuntimeException("The cache must not be null. See loadBeanById() in AbstractCdmEditorPresenter");
87
        }
88
    }
89

    
90
}
(16-16/19)