每个DAO中的EntityManager配置

pop*_*der 4 java spring jpa eclipselink java-ee

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

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

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

@PersistenceContext
private EntityManager em;
Run Code Online (Sandbox Code Playgroud)

我在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"/>
Run Code Online (Sandbox Code Playgroud)

来自Persistence.xml:

<persistence-unit name="xxxxx" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<-- class mappings -->
</persistence-unit>
Run Code Online (Sandbox Code Playgroud)

我对自己的所作所为感到困惑:

  1. EntityManager春天注射的吗?(我知道这@PersistenceContext是一个J2EE注释,所以想知道它是否是在没​​有Spring贡献的情况下注入的).

  2. 正如我已经提到的,我已经注入EntityManager了所有DAO课程.这是一个好习惯吗?或者我应该通过一个单独的类来制作Singleton PersistenceManager,它具有EntityManager属性有线,并且有 getEntityManager()方法?

  3. 如您所见,我已配置Spring事务.但是当我连续2-3次进行CRUD操作时,应用程序卡住并因EclipseLink异常而无法获取锁定,超时等失败.我在这里做错了什么或者丢失了任何事务配置?

  4. 通过上面的配置,我只能使用@Transactional默认值的注释PROPAGATION_REQUIRED,ISOLATION_DEFAULT.如果我为任何其他值(例如@Transactional(PROPAGATION_REQUIRED,ISOLATION_SERIALIZABLE)等)更改这些值,则 应用程序会抛出异常,因为不支持自定义隔离级别.我再次错过了任何配置吗?

    谢谢.

Boz*_*zho 8

  1. 是的,spring识别@PersistenceContext注释并注入实体管理器
  2. Spring负责这一点 - 它EntityManager在所有DAO中注入相同的实例.实际上,它会注入一个代理,以便每个请求使用不同的实体管理器.
  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>
    
    Run Code Online (Sandbox Code Playgroud)