基本原理。如何在春季+ hibernate+ = vaadin结束后使用懒惰

发布于 2025-01-20 07:37:32 字数 671 浏览 5 评论 0 原文

有客户实体与实体地址有一对多关系,因此有一个 list< address> getAddress 在客户地址中有三列,街道,城市和国家。

给出了为客户提供的JPAREPOSITORITIONY,在进行FindbyId(5)获取ID = 5的客户实体时,您在Vaadin Grid中显示该显示,然后有点掩盖了会话(或者在服务后立即关闭会话在服务拨打存储库,并在调用存储库并GGET gget to行?)。

然后,当您尝试扩展Cutomer时,以查看他的地址是否没有客户。GetAddress()呼叫会在幕后发生?既然它很懒惰,它将发出新的SQL查询,但没有会话打开会话这将导致懒惰化的感受。

这是我甚至遇到的情况,甚至只是将客户绑定到网格而不试图调用地址。 ,急切的加载授权可能会被证明是有害的。

但是,这不仅是与Vaadin有关的根本问题,而且与所有使用Hibernate有关的春季申请?我的意思是,所有使用stack都使用的应用程序都使用了渴望的关系?在上面的情况下,我看不出如何懒惰。当Customer.getAddress()调用时,应该打开新的会话吗?

我知道提取加入,但这意味着要编写自定义的SQL查询以填充DTO。如果您不想使用DTO并使用实体本身通过使用 customer.getAddress之类的关系来遍历traverse。 .get(0).getStreet ,您该怎么办?

There is the Customer entity which has a one to many relationship to entity Address,so there is a List<Address> getAddress in Customer.Entity Address has three columns,Street,City and Country.Fetch type between Customer and Address is Lazy.

Given a Jparepository for Customer, when doing findById(5) fetches the Customer entity for id=5.You display that in a Vaadin grid and then persumably the session closes (or does the session close immediately after the Service calls the Repository and ggets the rows?).

Then when on the grid you try to expand Cutomer in order to see his addresses isn't there a customer.getAddress() call going to happen behind the scenes?Since it is Lazy it will fire a new SQL query but with no session open it will cause a LazyInitializationException.

This is the very case I encountered even whne just binding Customer to the grid without making an attempt to call the Address.That has been solved by changing to Fetch type Eager.But if there are more relationships with Customer,like a customer having multiple Offices, loading entitires up front with Eager might prove detrimental.

BUT Isn't that a fundamental problem not just pertaining to Vaadin but to all Spring applications using hibernate? I mean are all the apps written with that stack all using relationships EAGER? In the scenario above I see not how you can go Lazy fetching. Should a new session be opened when customer.getAddress() is called?

I'm aware of the FETCH JOIN but that would mean write a custom SQL query to fill a DTO.if you don't want to use a DTO and use the Entities themselves to traverse by using the relationships like customer.getAddress.get(0).getStreet, what can you do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情释 2025-01-27 07:37:32

这是Spring MVC应用程序的常见问题(如您和DavidCyp评论)。有两个重要方面需要考虑到解决方案:

  • 通过一个侧面数据设计和用法,以及根据它们两个所需的数据库访问。每当要进行数据库访问(包括懒惰访问结果的访问)时,您应该进行开放的Hibernate会话,此外,所有参与访问权限的实体都必须附加到该会话上。因此,在您的情况下,当customer.getAddress发送到数据库时,您应该有一个会话,并且应将客户附加到该会话中。

  • 另一方面,有不同的方法来配置会话管理。您可以为整个Web请求附上一个会话,也可以在内部服务上附上“较小”会话。您可以在此处找到vaadin + Hibernate的博览会:


考虑到所有这些,对于您的情况,我会选择使用sessign-per-per-request模式(如上链接中所述),但是您可能会根据其他参数到其他应用条件。

然后,一旦确定了足够的会话管理,似乎有三个主要选择来解决问题:

  1. 使用急切的获取。
  2. 以编程方式检索以前的数据以访问它。因此,在检索客户时执行客户。这相当于急切的获取,但是它具有一个优势,您可以确定要在哪些情况下预先提取数据(例如,您可能有两种不同的视图,并且只需要其中一个中的预定数据)。作为负面的一面,它似乎有些丑陋。
  3. 保持关系为懒惰,在需要时检索数据,但是您必须确保您在那里有一个冬眠的会话,并且客户实体已附加到它(如果使用客户实体检索到客户实体,则可以使用合并另一个会话,也是上一个链接中的示例)。

This is a common problem to spring MVC applications (as you and davidcyp comment). There are two important aspects to take into account for the solution:

  • By one side data design and usage, and the database accesses that are required according to both of them. Whenever a database access is to be made (including accesses that are consequence of lazy accesses), you should have an open hibernate session, and additionally, all entities taking part in the access must be attached to that session. So, in your case, when the SQL code for customer.getAddress is sent to the database, you should have a session, and the customer should be attached to that session.

  • By other side, there are different ways to configure session management. You can have a session attached for a whole web request, or you can have "smaller" sessions, attached to inner services. You can find an exposition for vaadin + hibernate here: https://vaadin.com/docs/v7/framework/articles/UsingHibernateWithVaadin

Taking all this into account, for your situation I would choose probably to use the session-per-request pattern (as commented in the link above), but you perhaps have other arguments according to other application conditions.

Then, once you have decided the adequate session management, there seem to be three main options in order to solve the problem:

  1. Use EAGER fetching.
  2. Programmatically retrieve the data previously to access it. So, execute a customer.getAddress at the moment when the customer is retrieved. This is equivalent to EAGER fetching but it has the advantage that you can decide in which situations you want to pre-fetch the data (for example you might have two different views and only need that pre-fetched data in one of them). As a negative side, it might seem a bit uglier.
  3. Keep the relation as LAZY, retrieving data when you need it, but then you must be sure that you have an hibernate session there, and that the customer entity is attached to it (you can use merge for that if the customer entity was retrieved with another session, an example also in the previous link).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文