应用程序范围的托管 bean 死了吗?

Posted

技术标签:

【中文标题】应用程序范围的托管 bean 死了吗?【英文标题】:Application scoped Managed bean dying? 【发布时间】:2011-06-28 04:40:42 【问题描述】:

我有一个应用程序范围的托管 bean,其主要目的是为应用程序的其余部分提供较少的动态数据,例如所有可用的语言和更多的东西。

应用控制器

@ManagedBean(eager=true)
@ApplicationScoped
public class ApplicationController implements Serializable 
    private static final long serialVersionUID = 25488214212L;

    private List<Language> languages;
    private Map<Language, List<LevelDescription>> descriptionsPersonal;
    private Map<Language, List<LevelDescription>> descriptionsTechnical;
    private List<Integer> levels = new ArrayList<Integer>();

    @EJB private LanguageDao languageDao;
    @EJB private LevelDescriptionDao levelDescriptionDao;
    @EJB private IntraConnectionBean intraBean;
    @EJB private ApplicationBean appBean;

    public ApplicationController() 
    

    @PostConstruct
    public void init()
        languages = languageDao.findAll();
        descriptionsTechnical = new HashMap<Language, List<LevelDescription>>();
        descriptionsPersonal = new HashMap<Language, List<LevelDescription>>();
        for(int i = 0; i < 6; i++)
            levels.add(i);
        for(Language l : languages)
            List<LevelDescription> desc = levelDescriptionDao.findAll(l, true);
            if(!desc.isEmpty())
                descriptionsTechnical.put(l, desc);
            desc = levelDescriptionDao.findAll(l, false);
            if(!desc.isEmpty())
                descriptionsPersonal.put(l, desc);
        
    

    public List<Language> getLanguages()
        if(lang)
        return languages;
    

    public List<LevelDescription> getTechnicalItems(Language lang) 
        return descriptionsTechnical.get(lang);
    

    public List<LevelDescription> getPersonalItems(Language lang) 
        return descriptionsPersonal.get(lang);
    

    public List<Integer> getLevels()
        return levels;
    

这似乎工作正常。一阵子。将应用程序单独放置一段时间(可能是一个小时)时,我会出现非常奇怪的行为。 get 方法似乎要么开始返回空集合,要么返回带有看似正确但不适用于发布 selectOneMenus 的对象的集合。重新部署使其再次工作,这也使其难以进行试验,因为打开调试模式将通过重新部署使其再次工作。

什么基于时间的事件可能导致这种情况?这不是会话超时,我已经测试过将其设置为一分钟并让会话终止而不会导致此问题,它主要发生在开发服务器整晚不受干扰地运行后的早晨。所有 EJB 都是无状态的,我无法想象它们会成为问题。会不会是序列化问题?

我为如此分散而道歉,也许我以某种方式误解了应用程序范围 bean 的工作原理。任何帮助将不胜感激。

【问题讨论】:

我想问你,添加的语言是什么?应用程序应该始终在服务器上并运行,因此,如果我们添加任何内容,数据将不会改变.. ? 四年前我自己解决了这个问题。回答你的问题。语言可能会添加到应用程序的新版本中(从而导​​致服务器重启)。 【参考方案1】:

刚刚发现我的问题是:一个错误实现的 equals 方法。 equals 方法将比较对象的 id (Long),并使用 == 而不是 Long.equals。当对象的寿命比 JPA 缓存长时,这导致相等性始终为负(因为它们的物理地址在缓存失效并创建新对象之前是相同的)。

【讨论】:

以上是关于应用程序范围的托管 bean 死了吗?的主要内容,如果未能解决你的问题,请参考以下文章

将 JSF 托管 bean 迁移到 CDI 托管 bean

WELD-000072 声明钝化范围的托管 bean 必须具有钝化能力

JSF 2.x @ViewScoped 托管 bean 线程安全吗?

如何以编程方式注册 JSF 托管 bean?

mod_perl 死了吗?

是否有可能在运行时检测CDI托管bean的范围?