每个 DAO 中的 EntityManager 配置

发布于 2024-12-03 04:58:27 字数 2549 浏览 4 评论 0原文

我知道这是一个很长的问题,但我想问一切,因为我 被这些事情困扰了两个多星期,我可以在短时间内解决这个问题 本星期。请在这件事上指导我。

我正在使用 EclipseLink jpa 版本 2、Spring 3、jdk6、MySQL5 和 tomcat7。

我在每个 DAO 类中配置了以下内容。

@PersistenceContext
private EntityManager em;

我的 Spring xml 中有以下内容:

<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"  id="dataSource">
    <property name="url" value="jdbc:mysql://localhost:3306/xxxxx"/>
    <property name="username" value="xxxx"/>
    <property name="password" value="xxxx"/>
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
</bean>

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
    <property name="jpaDialect" ref="jpaDialect"/>
</bean>

<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
    <property name="jpaDialect" ref="jpaDialect"/>
</bean>

<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter" >
    <property name="showSql" value="true"/>
    <property name="generateDdl" value="true" />
</bean>

<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect"/>

来自 Persistence.xml:

<persistence-unit name="xxxxx" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<-- class mappings -->
</persistence-unit>

我对我所做的事情没有什么困惑:

  1. EntityManager 是由 Spring 注入的吗? (我知道 @PersistenceContext 是 J2EE注解,所以想知道它是否是在没​​有Spring贡献的情况下注入的)。

  2. 正如我已经提到的,我已在所有 DAO 类中注入了 EntityManager。是 这是一个好的做法吗?或者我应该通过像这样的单独的类来使其成为单例 PersistenceManager,它具有已连接的 EntityManager 属性,并且具有 getEntityManager() 方法?

  3. 正如你在上面看到的,我已经配置了 Spring 事务。但是当我做CRUD时 连续操作 2-3 次,应用程序卡住并且 EclipseLink 失败 异常说无法获得锁定、超时等。我在这里做错了什么吗? 缺少任何事务配置?

  4. 通过上述配置,我只能使用默认的@Transactional注释 值为 PROPAGATION_REQUIRED,ISOLATION_DEFAULT。如果我将这些更改为其他任何 值,例如 @Transactional(PROPAGATION_REQUIRED,ISOLATION_SERIALIZABLE) 等, 由于不支持自定义隔离级别,应用程序会引发异常。再说一次,我 我缺少任何配置吗?

    谢谢。

I understand that this is a very long question, but i wanted to ask everything because i'm
stuck with these things for more than 2 weeks and i'm in a situation to solve this within
this week. Please guide me in this matter.

I'm Using EclipseLink jpa version 2, Spring 3, jdk6, MySQL5 and tomcat7.

I have configured the following in each of my DAO classes.

@PersistenceContext
private EntityManager em;

I have the following in my Spring xml:

<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"  id="dataSource">
    <property name="url" value="jdbc:mysql://localhost:3306/xxxxx"/>
    <property name="username" value="xxxx"/>
    <property name="password" value="xxxx"/>
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
</bean>

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
    <property name="jpaDialect" ref="jpaDialect"/>
</bean>

<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
    <property name="jpaDialect" ref="jpaDialect"/>
</bean>

<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter" >
    <property name="showSql" value="true"/>
    <property name="generateDdl" value="true" />
</bean>

<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect"/>

From Persistence.xml:

<persistence-unit name="xxxxx" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<-- class mappings -->
</persistence-unit>

I've got few confusion about what i have done:

  1. Is the EntityManager injected by Spring? (I understand that @PersistenceContext is a
    J2EE annotation, so wondering whether it is injected without Spring's contribution).

  2. As i have already mentioned, i have injected EntityManager in all the DAO classes. Is
    this a good practice? or should i make it Singleton by having a separate class like
    PersistenceManager, which has EntityManager attribute wired, and have
    getEntityManager() method?

  3. As you can see above, i have configured Spring transactions. But when i do CRUD
    operations continuously for 2-3 times, application gets stuck and fails with EclipseLink
    exception saying unable to get lock, timeout etc. Am i doing anything wrong here or
    missing any transaction configurations??

  4. With the above configurations, i can only use @Transactional annotation with default
    values which are PROPAGATION_REQUIRED,ISOLATION_DEFAULT. If i change these for any other
    values, such as @Transactional(PROPAGATION_REQUIRED,ISOLATION_SERIALIZABLE) etc,
    application throws exception as Custom isolation levels are not supported. Again, am
    i missing any configurations?

    Thanks.

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

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

发布评论

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

评论(1

凉薄对峙 2024-12-10 04:58:27
  1. 是的,Spring 识别 @PersistenceContext 注释并注入实体管理器
  2. Spring 会负责这一点 - 它在所有 DAO 中注入相同的 EntityManager 实例。事实上,它注入了一个代理,以便每个请求使用不同的实体管理器。
  3. 通常一切都应该运行良好。您需要 才能使用 @Transactional
  4. JPA 仅支持默认隔离级别。您可以通过自定义 spring jpa 方言来解决此问题,但没有任何内置内容。方法是扩展XJpaDialect(在您的情况下为X=EclipseLink),覆盖beingTransaction,获取Connection(在eclipse-link中)特定方式),设置所需的隔离级别(可通过事务定义访问),并将其配置为 LocalContainerEntityManagerFactoryBean 的属性:

    <属性名称=“jpaDialect”>
        >
    
    
  1. Yes, spring recognizes the @PersistenceContext annotation and injects the entity manager
  2. Spring takes care of that - it injects the same EntityManager instance in all DAOs. In fact, it injects a proxy so that each request uses a different entity manager.
  3. Normally everything should run fine. You need <tx:annotation-driven /> in order to use @Transactional
  4. JPA only supports the default isolation level. You can work this around by customizing the spring jpa dialect, but there's nothing built-in. The way to go is extend XJpaDialect (in your case X=EclipseLink), override the beingTransaction, obtain the Connection (in an eclipse-link specific way), set the desired isolation level (accessible through the transaction definition), and configure this as a property of your LocalContainerEntityManagerFactoryBean:

    <property name="jpaDialect">
        <bean class="com.foo.util.persistence.EclipseLinkExtendedJpaDialect" />
    </property>
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文