1

记录多个实体我有带我有些怀疑这种特殊情况下: 我的A级与B中的一个一对多的关系:最便宜的方式/ GAE上

A 1----->* B 

其中,作为远据我所知,使他们的相关实例属于同一个实体组。 我必须检索一个特定的A实例和它的一个B,因此我搜索A并遍历其B列表以查找特定的B(始终通过Id进行搜索)。在那之后,我改变A和B的一个属性,并通过合并A.提交我的变化因此,这里是我的问题:

  1. 知道我必须检索A和B(因为我要同时修改),我应该进行2次搜索而不是迭代B列表?
  2. 进行2次搜索,对B的修改将会持续下去,如果我只坚持A?
  3. 会质疑1和2在这种情况下,相同的答案:
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做同样的事情,如果我做得对。哪一个更好?

回答

1

如果您知道该ID(并且您说您正在通过ID进行搜索),那么只需为A执行em.find,为B执行em.find。可悲的是,JPA API没有em.findAll。另一方面,JDO确实有pm.getObjectsById

+0

谢谢。你这么说是因为它比迭代B列表便宜,对吧? – Roberto 2012-02-16 11:37:51

+0

想想数据存储访问...获取A,然后获取B实体列表...或获取A,获得B.可能两个数据存储访问两者(查看日志,它会告诉您(使用最新版本的Google插件)),但是后者正在检索更少的信息(带宽) – DataNucleus 2012-02-16 13:19:39

+0

我认为在迭代列表(对列表中的每个元素进行一次搜索)时,会花费更多的读取操作。 – Roberto 2012-02-16 19:56:36

2

如果我理解正确,您不必遍历任何内容,而是在您喜欢的任何Query上使用filter()。例子(蟒蛇):

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

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

如果您使用的是Java的你有你的查询(more info)使用addFilter

+0

对不起,忘了说我使用Java和JPA。 – Roberto 2012-02-15 16:42:15

+0

@Roberto我用一些关于Java的链接更新了我的答案。 – Lipis 2012-02-15 16:54:10

+0

我不明白,过滤器使用情况如何转化为搜索次数或数据存储区读取次数?我该如何检索实体和祖先?请注意,我正在使用ID来查找两个实例。 – Roberto 2012-02-15 17:07:13

相关问题