我正在使用 JPA/EJB/JSF 开发一个 Java EE6 项目,并且在为实体设计多语言支持时遇到了一些麻烦。存在三个相关实体:
语言(有 id)
能力(有 id)
能力名称(有能力参考、语言参考和字符串)
Competence 具有对使用 Map 实现的 CompetenceName 的一对多引用,其中包含一个对象,用于存在 Competence 名称的每种语言。请注意,权限是动态创建的,因此它们的名称不能存在于资源包中。
在网页上列出能力时,我希望它们以当前登录用户的语言显示,这存储在 Session Scoped Managed Bean 中。
有没有什么好的方法可以在不破坏良好的 MVC 设计的情况下实现这一点?我的第一个想法是通过 FacesContext 直接从 Competence 实体中的“getName”方法获取会话范围 bean,并在 CompetenceNames 的映射中查找它,如下所示:
public class Competence
{
...
@MapKey(name="language")
@OneToMany(mappedBy="competence", cascade=CascadeType.ALL, orphanRemoval=true)
private Map<Language, CompetenceName> competenceNames;
public String getName(String controller){
FacesContext context = FacesContext.getCurrentInstance();
ELResolver resolver = context.getApplication().getELResolver();
SessionController sc = (SessionController)resolver.getValue(context.getELContext(), null, "sessionController");
Language language = sc.getLoggedInUser().getLanguage();
if(competenceNames.get(language) != null)
return competenceNames.get(language).getName();
else
return "resource missing";
}
这个解决方案感觉非常粗糙,因为实体依赖于控制器层,并且每次我想要它的名字时都必须获取一个会话控制器。更符合 MVC 的解决方案是采用 Language 参数,但这意味着来自 JSF 的每个调用都必须包含从会话范围的托管 bean 获取的语言,这也不是一个好的解决方案。
有没有人对这个问题有任何想法或设计模式?