具有客观性的安全嵌入式实体 [英] Safe embedded entity with objectify

查看:87
本文介绍了具有客观性的安全嵌入式实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个实体。

  @Entity 
公共类食谱{
@Id
私人长ID;
私人列表<步骤>脚步;
}
@实体
公共类步骤{
@Id
私有长ID;
私有字符串指令;
}

以下Clound Endpoint

  @ApiMethod(
name =insert,
path =recipe,
httpMethod = ApiMethod.HttpMethod.POST)
公共食谱插入(食谱食谱){
ofy()。save()。entities(recipe.getSteps())。now(); //多余?
ofy()。save()。entity(recipe).now();

logger.info(创建食谱ID:+ recipe.getId());

return ofy()。load()。entity(recipe).now();

我想知道如何跳过必须保存的步骤首先是嵌入的实体。两个实体的 Id 都没有设置。我想要物化自动创建这些。但如果不保存嵌入式实体,我会得到一个异常。


com.googlecode.objectify.SaveException:保存com.devmoon时出错。 meadule.backend.entities.Recipe@59e4ff19:您无法为具有空@Id的对象创建密钥。对象是com.devmoon.meadule.backend.entities.Step@589a3afb


由于我的对象结构会变得更加复杂,所以我需要找到一种方法来跳过这个手动步骤。

解决方案

我假设你正在尝试创建真正的嵌入式对象,而不是单独的对象存储在数据存储中并链接。你的额外save()实际上是保存单独的实体。您不需要这样做。



您有两种选择:


  1. Don给你的嵌入对象一个id。不要给它@实体,不要给它一个id字段(或至少消除@Id)。这只是一个POJO。 90%的时间,这是人们想要的嵌入对象。

  2. 使用分配器自己分配id,通常在您的(非默认)构造函数中。 $ b

假设你想要一个真正的带有真正键的嵌入式实体,#2可能就是你应该使用的。请记住,这个键有点异想天开,因为你实际上无法加载它;只有容器对象可以在数据存储中查找。



我建议更进一步,永远不要使用自动ID生成 。在实体的(非默认)构造函数中始终使用分配器。这确保实体始终拥有有效的,稳定的ID。如果您始终在事务开始之前分配ID,它会修复在重新尝试事务时可以创建的重复实体。填充空ID是一个坏主意,真的不应该添加到GAE中。


I have two entities.

@Entity
public class Recipe {
    @Id
    private Long id;
    private List<Step> steps;
}
@Entity
public class Step {
    @Id
    private Long id;
    private String instruction;
}

And the following Clound Endpoint

@ApiMethod(
        name = "insert",
        path = "recipe",
        httpMethod = ApiMethod.HttpMethod.POST)
public Recipe insert(Recipe recipe) {
    ofy().save().entities(recipe.getSteps()).now();  //superfluous?
    ofy().save().entity(recipe).now();

    logger.info("Created Recipe with ID: " + recipe.getId());

    return ofy().load().entity(recipe).now();
}

I'm wondering how do I skip the step where I have to save the emebedded entity first. The Id of neither entity is set. I want objectify to automatically create those. But if don't save the embedded entity I get an exception.

com.googlecode.objectify.SaveException: Error saving com.devmoon.meadule.backend.entities.Recipe@59e4ff19: You cannot create a Key for an object with a null @Id. Object was com.devmoon.meadule.backend.entities.Step@589a3afb

Since my object structure will get a lot more complex, I need to find a way to skip this manual step.

解决方案

I presume you are trying to create real embedded objects, not separate objects stored in the datastore and linked. Your extra save() is actually saving separate entities. You don't want that.

You have two options:

  1. Don't give your embedded object an id. Don't give it @Entity and don't give it an id field (or at least eliminate @Id). It's just a POJO. 90% of the time, this is what people want with embedded objects.
  2. Allocate the id yourself with the allocator, typically in your (non-default) constructor.

Assuming you want a true embedded entity with a real key, #2 is probably what you should use. Keep in mind that this key is somewhat whimsical since you can't actually load it; only the container object can be looked up in the datastore.

I suggest going one step further and never use automatic id generation for any entities ever. Always use the allocator in the (non-default) constructor of your entities. This ensures that entities always have a valid, stable id. If you always allocate the id before a transaction start, it fixes duplicate entities that can be created when a transaction gets retried. Populating null ids is just a bad idea all around and really should not have been added to GAE.

这篇关于具有客观性的安全嵌入式实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆