1

我有一个 bean,它有很多属性,其中一半是 n 对 n 关系。我还添加了额外的瞬态“ isEdited ”布尔值,以确保用户已经完成了一些更改,这样我就可以减少所有实体的 db 获取。我当前的问题有时我需要序列化我的 bean 并希望将属性与真实实例进行比较。我尝试的第一个解决方案来自apache commons-lang =>EqualsBuilder.reflectEqual();方法,它对我来说效果不佳,因为一些继承的项目没有以正确的方式实现 equals 方法,我无法编辑它们。我知道我可以添加 ajax 侦听器来更新已编辑的属性,或者我可以更新每个 setter 方法或新的 equals 实现。但我正在寻找更实用和通用的方式,这样我将来也可以使用这个实现。

所以我想要什么:(假设我有一个简单的 bean):

public class Foo {

    private String prop1;

    private String prop2;

    /**
     * @return the prop1
     */
    public String getProp1() {
        return prop1;
    }

    /**
     * @param prop1 the prop1 to set
     */
    public void setProp1(String prop1) {
        this.prop1 = prop1;
    }

    /**
     * @return the prop2
     */
    public String getProp2() {
        return prop2;
    }

    /**
     * @param prop2 the prop2 to set
     */
    public void setProp2(String prop2) {
        this.prop2 = prop2;
    }



}

比我的 bean 将实现一个EventListener接口,这个侦听器将处理所有设置器。如果调用任何 setter 方法(在初始化之后),则编辑的属性将设置为 true。

所以我的问题是添加动作/事件监听器来处理设置器的正确方法是什么?

编辑**我试过PropertyChangeListener但没有得到任何事件输出。如果我添加每个 setterspcs.firePropertyChange();方法,那么我可以通过这些方法直接设置isEdited是没有意义的。

4

1 回答 1

1

你不能有一个Map<String,Boolean>并用每个​​二传手更新它吗?以prop1为例:

public void setProp1(String prop1) { 
    if(!prop1.equals(this.prop1))
        updateMap.put("prop1", true);
    this.prop1 = prop1;
}

这样,在保存实体时,您将拥有一个包含该“元数据”的地图。

编辑:有一个缺陷很难,因为如果用户设置一个值,然后返回到原来的地图将保持真实。您可以通过使用另一个地图(或克隆您的对象)与原始值来比较两者来避免这种情况:

public void setProp1(String prop1) { 
    if(!prop1.equals(this.prop1) && !prop1.equals(ORIGINAL_VALUE))
        updateMap.put("prop1", true);
    else
        updateMap.put("prop1", false);
    this.prop1 = prop1;
}

编辑:亚当在方面是正确的,确实这是一个可能会花费你一些时间的改变。此外,如果您想使用反射,还有另一个问题,因为您与方法的结构有关。将来,如果您想更改方法的名称或类型,您也必须更新该反射助手类。

我建议在保存它们之前更新时间值,以便您可以将它们与原始值进行比较,但是如果您在没有 getter 的情况下直接访问字段/对象,这将涉及更改您的方法。

最后,第三种选择(总是有第三种)我认为您可能愿意做的就是valueChangeListener在您的组件中使用 's。例如:

<h:inputText id="prop1Input" value="#{bean.prop1}" valueChangeListener="#{bean.changesListener}"/>

你的 bean 应该有一个具有这种结构的方法:

public void changesListener(ValueChangeEvent e) {
    //Get the new value
    Object o = e.getNewValue();
    //get the component's id
    String componentId = e.getComponent().getId();
    //Cast the value and compare it, after that you should update a map. You are
    //going to need one anyway to know which field changed.
    boolean valueChanged = //compare against original value
    if(componentId.equals("prop1Input"));
    map.put("prop1", valueChanged);
}

关于这种方法的一个重要说明是,侦听器将在验证阶段执行。此侦听器的目的是能够处理新旧值,这似乎是您的情况。因为您也可以知道触发它的组件,所以您应该没问题。

于 2012-10-08T13:28:07.980 回答