每个DAO中的EntityManager配置

时间:2011-09-07 17:54:14

标签: java spring java-ee jpa eclipselink

我知道这是一个很长的问题,但我想问一切,因为我 坚持这些东西超过2周,我正在解决这个问题 本星期。请指导我这件事。

我正在使用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. Spring注入了EntityManager吗? (我知道@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)等, 应用程序抛出异常,因为不支持自定义隔离级别。再一次,我 我错过了任何配置?

    感谢。

1 个答案:

答案 0 :(得分:8)

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

    的属性
    <property name="jpaDialect">
        <bean class="com.foo.util.persistence.EclipseLinkExtendedJpaDialect" />
    </property>