16

その JavaDoc によると、PersistenceAnnotationBeanPostProcessor は、アノテーション @PersistenceContext を使用して EntityManager を注入する責任があるようです。この Bean が Spring アプリケーション コンテキスト xml で宣言されていないと、@PersistenceContext アノテーションが機能しないことを暗示しているようです。

しかし、私の実験に基づくと、これは真実ではありません。

Persistence.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
        http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0">
    <persistence-unit name="default" transaction-type="RESOURCE_LOCAL" />
</persistence>

Spring アプリケーション コンテキスト XML

<context:component-scan base-package="com.test.dao" />

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="persistenceUnitName" value="default"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="true"/>
            <property name="generateDdl" value="true"/>
            <property name="databasePlatform" value="org.hibernate.dialect.DerbyDialect"/>
        </bean>
    </property>
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.apache.derby.jdbc.ClientDriver"/>
    <property name="url" value="jdbc:derby://localhost:1527/c:\derbydb\mydb"/>
    <property name="username" value="APP"/>
    <property name="password" value="APP"/>
</bean>

<tx:annotation-driven/>

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

<!-- 
    <bean id="persistenceAnnotation" class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
 -->

UserDaoImpl

@Repository("userDao")
public class UserDaoImpl implements UserDao {

    @PersistenceContext
    protected EntityManager entityManager;

    @Transactional
    public void save(User user) {
            entityManager.persist(user);
    }
}

persistenceAnnotation Bean にコメントを付けてもコメントを外しても、結果は同じです。豆はそのままにしておいても問題ありませんが、この豆の用途は何ですか?

Spring 3.0.5 を使用しています。

誰かがこの Bean を取り出すと失敗するシナリオを提供できますか?

また、Spring をだますためだけに空の永続化ユニットを作成するのも好きではありません。幸いなことに、この問題は Spring 3.1.0 で対処されています。

4

2 に答える 2

16

PersistenceAnnotationBeanPostProcessor要素によって透過的にアクティブ化されます<context:component-scan />。正確に<context:annotation-config />は、Bean をアクティブ化するのは要素ですが、この要素は によって透過的にアクティブ化され<context:component-scan />ます。

于 2012-09-19T12:18:36.333 に答える
7

Oliver Gierke が述べたように、org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessorアノテーション ベースの構成を使用すると、Spring によって App Context に自動的に読み込まれます。その役割の 1 つは、注釈付きのプロパティEntityManagerFactoryを提供する適切なエンティティを検索するEntityManagerことです。@PersistenceContext

EntityManagerFactoryspring config/context に複数のBean があり@PersistenceContext、属性のない注釈があるunitName場合 (そのような Bean に付属するフレームワークを使用していて、フレームワーク コードに触れることができないとしましょう)、この例外に遭遇する可能性があります。org.springframework.beans.factory.NoUniqueBeanDefinitionException.

あなたがこれに同調した場合に備えて、私はこの回避策を見つけました:

<bean id="org.springframework.context.annotation.internalPersistenceAnnotationProcessor"
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" >
<property name="defaultPersistenceUnitName" value="entityManagerFactory"/>
</bean> 

PersistenceAnnotationBeanPostProcessorこれにより、Spring によってロードされたデフォルトが、新しいものでオーバーライドされますdefaultPersistenceUnitName

于 2014-07-28T15:25:13.440 に答える