【问题标题】:How to deal with 'cached' instance in @ViewScoped page?如何处理@ViewScoped 页面中的“缓存”实例?
【发布时间】:2019-01-13 08:01:22
【问题描述】:

JSFPrimefaceseclipselink 一起运行的应用,不是一个小应用,大约 100 个页面/bean 都可以完美运行

我在理解 @ViewScoped 页面的工作方式时遇到了一些麻烦,我有一个 select UI 组件,在我的 bean 中填充了一个简单的 List<People> 和一个后端 selectedPeople


// all getters, setters, JPA annotations, all good
public class People {
    private String name;
    private List<Car> cars;
}

@ManagedBean
@ViewScoped
public class PeopleBean {
    @EJB
    private Service sPeople;
    private People selectedPeople;
    private List<People> listPpl;

    @PostConstruct
    public void init(){
        listPpl = sPeople.readAll();      // always good, same as DB values
    }

    public People getSelectedPeople(){
       return selectedPeople;
    }

    public People setSelectedPeople(People p){     // p is an old element
       selectedPeople = p;                         // BREAKPOINT
    }

    // getter for the list too
    public void method(){
        Logger.getAnoymousLogger().severe(selectedPeople.getCars()); // the one the old people, not the ne contained in the actual list
    }
}

<p:selectOneMenu id="selectP" value="#{peopleBean.selectedPeople}" converted="#{genericSecuerdConverter}" >
    <p:ajax event="change" partialSubmit="true" listener="#{peopleBean.method()}" />
    <f:selectItems value="#{peopleBean.listPpl}" var="people" itemLabel="#{people.name}" itemValue="#{people}" />
</p:selectOneMenu>

使用顺序和问题是(从调试中获取的信息):

  • 转到peoplePage.xhtml选择元素所在的位置,列表元素的IDs#410, #411, #412(3人)
  • 转到modif.xhtml,更改第三个人(删除car,保存在数据库中(签入数据库))
  • 回到peoplePage.xhtml,列表没问题,IDs在调试中是#650, #651, #652
  • 更改selectUI 的值(来自null)以选择一个人,在断点处,p 似乎是#412 元素,因此其汽车的更改列表不可见,它不是来自listPpl(因为只包含有效元素并且对应于数据库),它是一种缓存

我试图禁用 ecpliselink 缓存状态EclipleLink cache

  • 更改 eclipselink 属性
  • 更改 JPA 属性
  • 使用@Cacheable(false)

没有任何效果,也没有进入私人导航,也没有清除浏览器缓存并返回页面,p 元素仍然是第一次加载时的旧元素

我以为@ViewScoped 允许每次打开一个页面就好像它是第一次一样,但似乎不是,无法确定元素可以存储/缓存的位置


编辑我暂时使用了一种解决方法,但这显然是最好的解决方案

public People setSelectedPeople(People p){    
    if(p!=null)
        selectedPeople = sPeople.read(p.getId());                         
}

【问题讨论】:

    标签: java jpa caching eclipselink


    【解决方案1】:

    您正在寻找的是@RequestScoped。每次您执行合适的 HTTP 请求时,它都会创建所有内容。否则不能保证销毁@ViewScoped bean。 Omnifaces 文档中的一个示例:ViewScoped

    例如,当用户使用浏览器的后退和前进按钮时,此功能可用于帮助重新创建页面。

    @RequestScoped 只要 HTTP 请求-响应存在,Bean 就会存在。它在 HTTP 请求时创建,并在与 HTTP 请求关联的 HTTP 响应完成时销毁。

    @ViewScoped 只要用户在浏览器窗口/选项卡中与同一个 JSF 视图交互,Bean 就存在。它是根据 HTTP 请求创建的,并在用户回发到其他视图时被销毁。

    描述来源:https://www.tutorialspoint.com/jsf/jsf_managed_beans.htm

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-09
      相关资源
      最近更新 更多