有没有办法禁用播放框架模型类的增强功能?
我问这个的原因是因为我想将模型对象序列化为JSON,但只要json序列化程序触及任何非初始化模型,
该模型将被初始化,导致额外的数据库命中,并且生成的json将使用不必要的模型对象膨胀。我尝试将models.*
从application.conf中排除,并使用ServerConfigStartup
来调用serverConfig.addClass(Model.class)
或调用serverConfig.addPackage("models")
,但这些都不适合我。
答案 0 :(得分:1)
Ebean要求增强模型类。如果没有增强,则不能将模型类与ebean一起使用。
因此,您的选择是,不要使用ebean,或者不要将模型对象序列化为JSON。后者被认为是最佳实践,将REST API数据对象绑定到数据库模型不是一个好主意,因为您现在遇到的问题 - 两个模型通常在概念上不同 - 数据库模型引用了其他模型,而JSON模型没有。因此,使用不同的类来表示不同的模型。
还有另一种选择,使用像@JsonIgnore这样的杰克逊注释来忽略这些属性。但实际上,这是一个滑坡,随着你的代码库不断发展,当你开始在你的类上使用更多这些注释并保持模型时,几乎无法推断你的JSON会是什么样子,确保你不会破坏您的公共REST API变成了一场噩梦。
答案 1 :(得分:0)
我找到了一种方法来加载json序列化过程中不需要的模型。 首先,我必须使用以下方法修改Jackson序列化模型对象的方式:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.PUBLIC_ONLY);
这迫使杰克逊直接使用该领域,但你的模范领域必须是公开的。这还不够,因为在序列化过程中仍会加载未初始化的模型集。 为了解决这个问题,我不得不在序列化过程之前使用反射使集合为空,如下所示:
for (Field field : model.getClass().getFields())
{
Object fieldObject = field.get(model);
if (fieldObject instanceof BeanSet)
{
BeanSet beanSet = (BeanSet) fieldObject;
//checks if the set is loaded or not
if (beanSet.isReference())
{
field.set(model, null);
}
}
}
现在您的模型可以安全地传递给Jackson序列化程序,而不会在序列化过程中加载未初始化的模型对象。
String jsonString = objectMapper.writeValueAsString(model);
JsonNode jsonNode = Json.parse(jsonString);
使用@JsonIgnore
也会起作用,但从长远来看它是不可靠的,正如詹姆斯提到的那样,因为您可能需要稍后忽略的模型对象。