问题描述
我想避免使用样板代码来创建 SelectItem 列表以在视图和模型之间映射我的实体/dto,所以我使用了这个 通用对象转换器的片段:
I want to avoid boiler plate code for creating a list of SelectItems to map my entities/dtos between view and model, so I used this snippet of a generic object converter:
@FacesConverter(value = "objectConverter")
public class ObjectConverter implements Converter {
private static Map<Object, String> entities = new WeakHashMap<Object, String>();
@Override
public String getAsString(FacesContext context, UIComponent component, Object entity) {
synchronized (entities) {
if (!entities.containsKey(entity)) {
String uuid = UUID.randomUUID().toString();
entities.put(entity, uuid);
return uuid;
} else {
return entities.get(entity);
}
}
}
@Override
public Object getAsObject(FacesContext context, UIComponent component, String uuid) {
for (Entry<Object, String> entry : entities.entrySet()) {
if (entry.getValue().equals(uuid)) {
return entry.getKey();
}
}
return null;
}
}
对于类似问题已经有很多答案,但我想要一个普通的解决方案(没有 *faces).以下几点仍然让我不确定我的片段的质量:
There are already many answers to similliar questions, but I want a vanilla solution (without *faces). The following points still leave me uncertain about the quality of my snippet:
- 如果这么简单,为什么没有一个通用的对象转换器内置到 JSF?
- 为什么这么多人仍在使用 SelectItems?使用通用方法不是更灵活吗?例如.#{dto.label} 可以快速变成#{dto.otherLabel}.
- 鉴于范围只是在视图和模型之间进行映射,通用方法有什么主要缺点吗?
- If it was that easy, why isn't there a generic object converter build into JSF?
- Why are so many people still using SelectItems? Isn't there more flexibility by using the generic approach? E.g. #{dto.label} can be quickly changed into #{dto.otherLabel}.
- Given the scope is just to map between view and model, is there any major downside of the generic approach?
推荐答案
这种方法笨拙且内存效率低下.
This approach is hacky and memory inefficient.
在小型应用程序中没问题",但在具有数万或数十万个潜在实体的大型应用程序中绝对不是这样,这些实体可以在 f:selectItems
中引用.而且,如此大的应用程序通常具有二级实体缓存.WeakHashMap
变得无用,只有当实体从底层数据存储区(因此也从二级实体缓存中)物理删除时才有效.
It's "okay" in a small application, but definitely not in a large application with tens or hundreds of thousands of potential entities around which could be referenced in a f:selectItems
. Moreover, such a large application has generally a second level entity cache. The WeakHashMap
becomes then useless and is only effective when an entity is physically removed from the underlying datastore (and thus also from second level entity cache).
它当然有一个有趣"的因素,但我真的不建议在大量生产"中使用它.
It has certainly a "fun" factor, but I'd really not recommend using it in "heavy production".
如果您不想使用实用程序库中的现有解决方案,例如 OmniFaces SelectItemsConverter
正如您已经发现的那样,它基本上是完全无状态的并且不使用任何 DAO/Service 调用,那么您最好的选择是使用公共基接口/类抽象所有实体并挂钩转换器就那个.这只仍然需要一个 DAO/Service 调用.这已在此问答中详细说明:为实体实现转换器Java 泛型.
If you don't want to use an existing solution from an utility library like OmniFaces SelectItemsConverter
as you already found, which is basically completely stateless and doesn't use any DAO/Service call, then your best bet is to abstract all your entities with a common base interface/class and hook the converter on that instead. This only still requires a DAO/Service call. This has been fleshed out in detail in this Q&A: Implement converters for entities with Java Generics.
这篇关于反对具有静态 WeakHashMap 的通用 JSF 对象转换器的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!