开发者

In spring, what code is used to inject the value for the @PersistenceContext annotated variables?

Using a ClassPathXmlApplicationContext object I want to get the same EntityManager that is being used by other parts of the app开发者_如何学JAVA which get it injected via:

@PersistenceContext(unitName="accessControlDb") private EntityManager em;

Using ctx.getBean("access-emf") I can get the EntityManagerFactory which is defined in the applicationContext.xml. Using that I can create a new EntityManager, but I can't get the existing EntityManager used by the rest of the app.

I just can't figure out what code is executed to inject the value for the @PersistenceContext annotation.

<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/>


<bean id="innerNgsdpDataSource" class="org.enhydra.jdbc.standard.StandardXADataSource">
    <property name="driverName" value="${ngsdp.jdbc.driver}"/>
    <property name="url" value="${ngsdp.jdbc.url}"/>
    <property name="user" value="${ngsdp.jdbc.username}"/>
    <property name="password" value="${ngsdp.jdbc.password}"/>
    <property name="transactionManager" ref="jotm"/>
</bean>

<bean id="ngsdpDataSource" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource">
    <property name="transactionManager" ref="jotm"/>
    <property name="dataSource" ref="innerNgsdpDataSource"/>
    <property name="user" value="${ngsdp.jdbc.username}"/>
    <property name="password" value="${ngsdp.jdbc.password}"/>
    <property name="maxSize" value="4"/>

    <property name="checkLevelObject" value="2"/>
    <property name="jdbcTestStmt" value="select 1 from dual"/>
</bean>

<bean id="myEmf" name="moservices" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="ngsdpDataSource"/>
    <property name="persistenceXmlLocation" value="WEB-INF/moservices-persistence.xml" />
    <property name="jpaVendorAdapter" ref="hibernate_jpa_vendor_adapter" />
    <property name="jpaPropertyMap" ref="jpa_property_map"/>
    <property name="jpaDialect" ref="hibernate_jpa_dialect"/>
</bean>


If using spring-managed transactions, you can get the current EntityManager by calling

EntityManagerFactory emFactory = ctx.getBean("access-emf");
EntityManagerHolder emHolder = 
        (EntityManagerHolder) TransactionSynchronizationManager.getResource(emFactory);
EntityManager em = emHolder.getEntityManager();

This is most often the current EntityManager. But this is something which should be avoided (except possibly in unit-tests), as stated in the spring docs:

To be used by resource management code but not by typical application code

Another approach might be to intercept your service calls using Spring AOP, inject the @PersistenceContext in the advice, and set in in a ThreadLocal of yours. Later, you can get it from that ThreadLocal.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜