在GAE上检索/记录多个实体的最便宜方式

时间:2012-02-15 16:19:28

标签: java google-app-engine jpa transactions google-cloud-datastore

我有这个具体案例给我带来一些疑问: 我的A级与B有一对多的关系:

A  1----->*  B

据我所知,其相关实例属于同一实体组。 我必须检索一个特定的A实例和一个B,所以我搜索A并遍历其B列表以找到特定的B(总是按Id搜索)。之后,我更改了A和B的一个属性,并通过合并A来提交我的更改。所以这是我的问题:

  1. 知道我必须检索A和B(因为我必须修改它们),我应该进行2次搜索而不是迭代B列表吗?
  2. 进行2次搜索,如果我只坚持A?
  3. ,将继续对B进行修改
  4. 在这种情况下,问题1和2是否会有相同的答案:
  5. A  1----->*  C  1----->*  B
    

    用一些代码补充问题:

    @Entity
    public class A
    {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Key key;
    
        private int aField;
    
        @OneToMany(cascade={CascadeType.ALL})
        private List<B> bList;
    
        //...
    }
    
    @Entity
    public class B
    {
         @Id
         @GeneratedValue(strategy = GenerationType.IDENTITY)
         private Key key;
    
         private int someBField;
    
         // no way to get A from here...
    
         //...
    }
    
    public void someService1(Key aKey, Key bKey)
    {
         //...
    
         // Here, I'm sure that bKey is of an entity son of aKey entity (I trust the client)
         A a = entityManager.find(A.class, aKey);
         a.setAField(a.getAField()++);
    
         for(B b : a.getBList())
              if(b.getKey().equals(bKey))
                    b.setSomeBField(b.getSomeBField()++);
    
         entityManager.merge(a);
    
         //...
    }
    
    public void someService2(Key aKey, Key bKey)
    {
         //...
    
         // Here, I'm sure that bKey is of an entity son of aKey entity (I trust the client)
         A a = entityManager.find(A.class, aKey);
         a.setAField(a.getAField()++);
    
         B b = entityManager.find(B.class, bKey);
         b.setSomeBField(b.getSomeBField()++);
    
         entityManager.merge(a);
    
         //...
    }
    

    好吧,如果我做的一切正确,someService1和someService2都会做同样的事情。哪一个更好?

2 个答案:

答案 0 :(得分:2)

如果我理解正确,您不必迭代任何内容,而是在您喜欢的任何Query上使用filter()。示例(Python):

query.filter('height >', 42).filter('city = ', 'Seattle')

query.filter('user = ', users.get_current_user())

如果您使用的是Java,则会在查询中使用addFiltermore info)。

答案 1 :(得分:1)

如果您知道ID(并且您说您正在按ID搜索),那么只需为A执行em.find,为B.执行em.find两次调用。遗憾的是,JPA API没有em.findAll。另一方面,JDO确实有pm.getObjectsById