1

Spring Bean として初期化される Spring、JPA、および Dynamic Proxy DAO クラスに問題があります。この特定のプロジェクトは、永続性/トランザクション側でしばらくの間私を悩ませてきました。これを完全に解決したいと思います。

まず、DAO インターフェイスのメソッドを次に示します。

/**
 * Perform a named query using numbered parameters and return the results as a list
 * @param name
 * @param params
 * @return query results
 */
List getNQasList(String name, Object... params);

この Bean は、postProcessBeanFactory メソッドを使用して Spring に自動的に登録されます。

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

    this.beanFactory = beanFactory;
    for (Class entityClass : this.getPersistedClassList()) {
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        ConstructorArgumentValues constructorVals = new ConstructorArgumentValues();
        constructorVals.addIndexedArgumentValue(0, entityClass);
        beanDefinition.setConstructorArgumentValues(constructorVals);
        beanDefinition.setBeanClass(GenericDAOImpl.class);
        beanDefinition.setAutowireCandidate(true);
        beanDefinition.setLazyInit(true);
        beanDefinition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);
        String simpleName = entityClass.getSimpleName();
        String convertedName = "" + simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1) + "Dao";
        registry.registerBeanDefinition(convertedName, beanDefinition);
    }
}

メソッド getPersistedClassList() は persistence.xml を読み取り、すべての JPA クラスを見つけます。上記のメソッドは、これらの各インスタンスを Spring に登録し、変数「entityNameDao」によって簡単にアクセスできるようにします。このクラスはトランザクション クラスであるため、Dynamic Java Proxy として初期化されます。ここから問題が始まります。JSF はもはやそのインターフェースによってオブジェクトを認識しませんが、プロキシを直接見ます。これは実際、上記のメソッド定義を次のように示しています。

List getNQasList(String name, Object[] params);

これにより、Object... params 署名メソッドよりも JSF からのアクセスがはるかに難しくなります。JSF にこれらのオブジェクトをインターフェイスで認識させたり、Spring にそれらの動的プロキシを作成しないように説得したりする方法はありますか? または、ELで次のことを行うにはどうすればよいですか?試してみると、中括弧に関するエラーが発生します:

new Object[] {...}

トランザクションのアドバイスを含む永続性に関連する私の春の設定は、適切な測定のために以下に含まれています。

<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="${JDBC_CONNECTION_STRING}?autoReconnect=true&amp;useUnicode=true&amp;connectionCollation=utf8_general_ci&amp;characterSetResults=utf8"/>
    <property name="username" value="${PARAM1}"/>
    <property name="password" value="${PARAM2}"/>
    <property name="validationQuery" value="select 1"/>
</bean>

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

<context:annotation-config/>

<!-- Enable aspectj based transactions -->
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager" />
<!-- the transactional advice (i.e. what 'happens'; see the <aop:advisor/> bean below) -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- the transactional semantics... -->
    <tx:attributes>
        <!-- all methods starting with 'get' are read-only -->
        <tx:method name="get*" read-only="true"/>
        <!-- other methods use the default transaction settings (see below) -->
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

<!-- ensure that the above transactional advice runs for any execution
  of an operation defined by the GenericDAOImpl class -->
<aop:config>
    <aop:pointcut id="DaoOps" expression="execution(* daos.GenericDAOImpl.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="DaoOps"/>
</aop:config>

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" >
            <property name="showSql" value="true"/>
        </bean>
    </property>
</bean>
4

0 に答える 0