java - JPA Web 应用程序管理策略

标签 java hibernate jpa jakarta-ee

我们目前正在开发一个使用 JPA 作为我们的数据访问层的 J2EE 网络应用程序。我们目前正在考虑几种不同的策略来在我们的应用程序中使用缓存。

  1. > 为每个请求创建一个 EntityManager
    • > 在请求范围内获取缓存,但在请求结束时丢失缓存
    • > 使回滚整个请求的任何更改变得容易
  2. > 为每个 Http Session 创建一个 EntityManager
    • > 在 session 范围内获取缓存
    • > 使事务变得更加复杂,必须为每个请求创建一个新事务,然后能够回滚每个请求的更改

我在 Hibernate 文档中看到了这两种策略。我的问题是哪个使用更广泛,如果我们在每个 session 中执行 EntityManager,我们是否会通过在不同的请求线程中使用相同的 EntityManager 来遇到同步问题?

最佳答案

更广泛使用的方法是为每个请求创建一个 EntityManager。但是,这应该对您隐藏。您应该使用一些依赖项注入(inject)机制 (spring/CDI/EJB),该机制将在放置 @PersistenceContext 的位置注入(inject)正确的 EntityManager

如果您对在您的 bean 是某种单例(一个无状态 bean/一个作用域单例的 spring bean)的常见情况下如何实现这一点感兴趣 - 容器实际上在目标对象中注入(inject)了一个代理。每次咨询代理时,它都会获取 current EntityManager 实例,该实例(至少在 spring 的情况下)绑定(bind)到 ThreadLocal(在这种情况下=请求)

更新:如果您想在自己开发的框架中实现此功能,请使用 cglib/javassist/JDK 代理并将其注入(inject)到 @PersistenceContext 所在的位置。请求 = 线程。在每个需要数据访问的请求上,创建一个新的 EntityManager 并将其存储在 ThreadLocal 中。记得最后清理它,因为 servlet 容器会重用线程。从代理中,您可以获得当前的 ThreadLocal 值。

但如果您对项目的了解不深,那么我建议您转向更稳定的东西,例如 spring、cdi 或 guice。

关于java - JPA Web 应用程序管理策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4418979/

相关文章:

java - Gradle:Springboot 重写依赖项(jersey 和 apache httpclient)

java - JDK、JRE 中的内部类、嵌套类、本地类和匿名类示例

java - java中的序列化

java - 当没有互联网连接时,Hibernate 给出错误为 "Access to DialectResolutionInfo cannot be null when ' hibernate.dialect' not set"

java - 使用 hibernate/jpa/memcache 缓存大数据集?

java - 在 Hibernate 中设置参数值时指定字符串类型

java - 从可穿戴设备发送消息到手机,然后立即回复

java - JPA如何在双向ManyToOne中保留父级

java - 为什么每次调用findById()时Calendar字段都会自动增加

java - Spring JPA 不为实体创建表