2011-11-16 62 views
0

我的豆腐看起来像这样:物化+ JSP:显示1:N的关系

@Entity 
public class Fattura { 

    @Id 
    Long id; 

    @NotEmpty 
    String numero; 

    @Min(value=0) 
    Double importo; 

    Key<User> utente; 

    // gets & sets.... 
} 

的“utente”属性是另外一个bean我创建的关键:一个“Fattura”只能有一个“用户” ,一个“用户”可以有很多“Fattura” S

我的Spring MVC的控制器将管理一个请求Fattura的列表,并在一个简单的JSP显示出来:

@RequestMapping(value = "/fatture" , method = RequestMethod.GET) 
    public ModelAndView leFatture() { 

     ModelAndView mav = new ModelAndView("fatture"); 


     mav.addObject("fatture",fatturaService.listFatture()); 

     return mav; 
    } 

的JSP代码非常简单:仅在表中一个foreach循环

我的问题是:

我怎么能显示“utente”?

我唯一的一点是它的关键,但我想这样做$ {} fattura.utente.firstName在我JSP,我该怎么办呢?

回答

1

不幸的是,你将不得不在你的DAO类中手动获取“utente”。 Objectify中没有像Twig那样的自动获取。在我的POJO我有以下领域

@Transient private Organization sender;    // Pickup location (for client RPC) 
transient private Key<Organization> senderKey;  // Pickup location (for Datastore) 

我从数据存储加载实体,然后手动组织使用senderKey加载。

在新Objectify4,你就可以做你想做的是这样的:

class Beastie { 
    @Parent 
    @Load 
    ParentThing parent; 

    @Id Long id; 

    @Load({"bigGroup", "smallGroup"}) 
    SomeThing some; 

    @Load("bigGroup") 
    List<OtherThing> others; 

    @Load 
    Ref<OtherThing> refToOtherThing; 

    Ref<OtherThing> anotherRef; // this one is never fetched automatically 
} 

Here是不断变化的新版本的设计文件。

2011年11月17日更新:这是个大新闻。 Twig作者约翰帕特森今天加入Objectify项目。

+0

我怀疑这样的事情......所以我必须保持重复属性为每个键的关系?这不太好!你建议我使用Twig还​​是JDO/JPA? –

+1

我通过链接到Objectify4 doc更新了我的答案。我在一个月前有过确切的想法,法比奥。我最终选择了Objectify,因为我的项目会在很大的负载下工作,并且我希望有一个干净的简单代码,让我了解所发生的一切。我正在考虑Twig,但最近似乎项目得不到支持。根据JPA我喜欢它,但因为数据存储不是RDBMS GAE的JPA实现有许多奇怪的限制,而且它会对数据存储进行大量冗余调用,这会花费您真正的资金。 – expert

+0

很棒的回答!我想知道新的@Load将如何适合我的“客户 - 发票”用例,但我相信会有出色的文档。我也从使用JDE和GAE的恐怖评论中看到了Objectify。你知道Objectify是否会得到很长时间的支持(我未来的项目需要一些严格的可靠性)? –

1

我知道这听起来很烦人,您必须手动获取这两个对象,但它确实是非常有用的知道你的工作量增加了一倍,并且时间这么做 - 每个“获取”调用需要一段时间,第二个在第一次完成之前不会开始。它是一个典型的NoSQL环境,你不应该经常需要有两个独立的实体 - 你有这样一个原因吗?

只有两个原因,我可以很容易地想到:

  1. 类引用同类型的另一个对象 - 这是物化的文件,其中一个人有自己的配偶参考的例子,谁也是一个人。

  2. 您将另一个嵌入到其中的类(您的案例中的“Fattura”)中有大量数据,您不想在同一时间获取“用户”而且您需要的用户比自己需要的“Fattura”和“User”更频繁。当你需要“Fattura”时,需要有相当多的数据值得额外的数据存储库调用。

+0

我无法理解你的答案100%....“它是一个典型的NoSQL环境,你不应该经常需要有两个独立的实体”......但是我确实需要像使用RDBMS一样使用数据存储,不幸的是,所以我想要做的只是一个简单的手动“加入”。你如何在objectify-gae中编写一个简单的一对多关系?考虑一下像OFFICE这样的基本案例(1)=> PERSON(MANY) –

+0

“这是一个典型的NoSQL环境,你不应该经常需要有两个独立的实体 - 你有这样一个原因吗?”你能简单地向我解释一下吗? –

+0

对不起,我原以为你试图代表一对一的关系,这通常不是必需的。如果你想展示一对多,这取决于你如何使用它最好。例如,您可以使用office对象上的列表列出办公室中的所有用户。你最常用的是什么?您是否更经常地寻找用户所属的办公室或寻找办公室中的用户列表? – mjaggard

-1

您不一定非得使用临时字段来获取对象。

这工作:

public User getUtente() { 
    Objectify ofy = ObjectifyService.begin(); 
    return ofy.get(utenteKey); 
} 

这当然会做一个数据存储的get()每次调用getter时。您可以通过在您的用户实体上使用@Cached来改善这一点,以便在第一次调用后它们变为memcache调用。内存缓存是好的,但我们可以使用会话缓存做一个好一点:

public User getUtente() { 
    Objectify ofy = myOfyProvider.get(); 
    return ofy.get(utenteKey); 
} 

这里的关键是,你需要提供(通过myOfyProvider)绑定到当前的请求/线程客观化的一个实例并且启用了会话缓存。 (即,对于任何给定的请求,myOfyProvider.get()应返回Objectify的相同实例)

在此设置中,每次调用getter时,会从会话缓存中返回完全相同的User实例;从该实体的初始加载之后,不会对数据存储/ memcache发出任何请求。

+0

我已经明白:但我不希望我的实体POJO绑定/耦合到持久层! –