gpt4 book ai didi

java - 如何高效使用EntityManager?

转载 作者:行者123 更新时间:2023-12-02 03:24:58 25 4
gpt4 key购买 nike

我最近读了很多关于Java持久化的书籍和文章,读得越多,我对如何正确使用JPA高效越感到困惑。

现在,我为每种类型的实体提供了简单的服务层,它负责持久化、删除、搜索等。它获取EntityManagerFactorysingleton util类,创建一个EntityManager执行事务,然后关闭 EntityManager。 EMF 仅在应用程序关闭时关闭。如果我理解正确的话,通过关闭 EntityManager我的所有对象(与其相关)都会分离。通过更改对象中的任何值,它们不会被持久化,所以我认为情况就是这样。

在一本书中,我读到我应该将服务类设置为@Stateless beans,并将注入(inject)EntityManager作为 @PersistenceContext 在其中。这样,我将拥有与我拥有的许多服务类相同数量的 EntityManager(或者它是否足够智能,可以只注入(inject)一个?)。我假设可能存在这样的情况:一个对象由多个 EntityManager 处理,这是低效的,可能会导致错误。我可以使 EntityManager 成为一个单例,它保存并管理所有内容,并像 EMF 一样贯穿整个应用程序生命周期吗?

据我所知,EntityManager 应在每次事务后关闭,但随后我对托管部分感到困惑:

就我而言:

Car car = CarService.findOneById(somelong); //this method returns an already detached object, nothing is ever in managed state
car.setColor("yellow");
CarService.update(car); //updates the db

(这对我来说还不是问题,只是一个不必要的坏处,直到 LAZY fetch 发挥作用。)

我认为它应该如何工作:

Car car = CarService.findOneById(somelong); //does not close the EM
car.setColor("yellow"); //by this call the EM detects(?) and persists the change

有哪些方法可以实现这一目标,哪种方法被认为是最佳实践?如果您能给我每个层的示例,我将不胜感激。

提前谢谢您!

P.S.:我知道这个问题非常广泛,但我希望有人能抹去我脑海中的问号。

最佳答案

In a book I've read that I should make the service classes @Stateless beans, and inject the EntityManager as @PersistenceContext in them. That way I'll have the same amount of EntityManagers as many service classes I have

没有。您将获得绑定(bind)到当前事务的持久性上下文。简而言之,容器会做你自己正在做的事情,除了如果服务 A 调用服务 B,服务 B 调用服务 C,服务 C 调用服务 D,并且它们都共享相同的事务上下文,它们也将获得相同的持久性语境。当事务关闭时,持久化上下文也会被关闭。

Car car = CarService.findOneById(somelong); //does not close the EM
car.setColor("yellow"); //by this call the EM detects(?) and persists the change

只要您在事务内部而不是外部执行此操作,这将自动使颜色变化持久。

根据您的描述,我了解到您的服务并不是真正的服务。它们只是 DAO:它们持久存在并查找单一类型的实体,并且不包含任何业务逻辑。那不是应该处理交易的地方。事务应该在真正的业务服务层中处理,该层实现应用程序的事务用例。

例如,假设您开发一个银行应用程序。典型的用例不是减少帐户余额。或者增加账户余额。或者增加银行自有账户余额。一个典型的用例是在帐户之间实现资金转账。这意味着单个交易必须:

  • 查找发射器帐户
  • 找到接收者帐户
  • 检查转移是否可以完成
  • 计算银行通过转账赚取的百分比
  • 减少发射者账户余额
  • 将赚取的金额添加到银行帐户
  • 增加接收者帐户余额
  • 将转账操作添加到发射者账户
  • 将转账操作添加到接收者帐户

此用例将使用多个 DAO:AccountDAO、OperationDAO、BankAccountDAO 等,但所有操作都应在单个事务中完成。整个事务将使用一个独特的持久化上下文,其中所有实体都受到管理,因此所有更改都会自动持久化,而无需在任何 DAO 上调用 update()

关于java - 如何高效使用EntityManager?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39076960/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com