Использование Spring в качестве контейнера JPA - PullRequest
0 голосов
/ 10 июня 2010

Я нашел эту статью, в которой говорится об использовании Spring в качестве контейнера JPA:

http://java.sys -con.com / node / 366275

Я никогда не использовалSpring до этого, и я пытаюсь заставить это работать, и надеюсь, что кто-то может помочь мне.

В статье говорится, что вам нужно аннотировать bean-компонент Spring с @Transactional, а методы / поля с @PersistenceContext, чтобы обеспечитьподдержка транзакций и внедрение менеджера сущностей.

Есть ли что-то, что определяет бин как "Spring Bean"?У меня есть bean-класс, который реализует операции CRUD с сущностями, используя обобщенные значения:

@Transactional
public class GenericCrudServiceBean implements GenericCrudService
{
    @PersistenceContext(unitName="MyData")
    private EntityManager em;

    @Override
    @PersistenceContext
    public <T> T create(T t)
    {
        em.persist(t);
        return t;
    }

    @Override
    @PersistenceContext
    public <T> void delete(T t)
    {
        t = em.merge(t);
        em.remove(t);
    }
...
...
...
    @Override
    @PersistenceContext
    public List<?> findWithNamedQuery(String queryName)
    {
        return em.createNamedQuery(queryName).getResultList();
    }
}

Изначально у меня была только эта аннотация контекста постоянства:

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

, но при вызове findWithNamedQuery было нулевое em,Затем я также прокомментировал методы, но они все еще нулевые (без инъекций?).

Мне было интересно, не связано ли это с тем, что мой бин не распознается как «Spring».

Я выполнил настройку как мог, следуя указаниям в статье, включая настройку следующего в моем файле context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:tx="http://www.springframework.org/schema/tx"
    tx:schemaLocation="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="MyData" />
        <property name="dataSource" ref="dataSource" />
        <property name="loadTimeWeaver"
            class="org.springframework.classloading.ReflectiveLoadTimeWeaver" />
        <property name="jpaVendorAdapter" ref="jpaAdapter" />
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@localhost:1521:MySID" />
        <property name="username" value="user" />
        <property name="password" value="password" />
        <property name="initialSize" value="3" />
        <property name="maxActive" value="10" />
    </bean>

    <bean id="jpaAdapter"
        class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
        <property name="databasePlatform"
            value="org.eclipse.persistence.platform.database.OraclePlatform" />
        <property name="showSql" value="true" />
    </bean>

    <bean
        class="org.springframework.ormmjpa.support.PersistenceAnnotationBeanPostProcessor" />
    <tx:annotation-driven />
</beans>

Я догадался, что они принадлежали файлу context.xml, потому что статья никогдаконкретно сказано, какой файл является файлом "контекста приложения".Если это не так, пожалуйста, дайте мне знать.

Ответы [ 3 ]

0 голосов
/ 10 июня 2010

В статье говорится, что вам необходимо аннотировать bean-компонент Spring с @Transactional, а методы / поля - с помощью @PersistenceContext, чтобы обеспечить поддержку транзакций и внедрить менеджер сущностей.

Это правильно, и вы не должны добавлять @PersistenceContext в ваши методы, только в атрибут private EntityManager em.

Есть ли что-то, что определяет бин как "Spring"Bean "?

Это bean-компонент, управляемый контейнером Spring (т. Е. Spring управляет своим жизненным циклом, связывает его с другими Spring-компонентами и т. Д.).Это, конечно, подразумевает, что вы в какой-то момент создаете контейнер Spring.

Я догадался, что они принадлежат файлу context.xml, поскольку в статье никогда не указывалось, какой файл является файлом "контекста приложения".,Если это не так, пожалуйста, дайте мне знать.

Это относится к файлу контекста приложения, который является просто файлом XML, и имя на самом деле не имеет значения, пока вы говорите загрузке контейнера SpringЭто.И на самом деле, это большой вопрос: как вы запускаете свой код ?

В статье запускается пример из тестового примера, который расширяет класс Spring, предоставляя поддержку Spring (я имею в виду, что он создаст для вас контейнер Spring) и позволяя сообщать Spring, какие файлы контекста приложениязагрузить (в данном случае my-spring-config.xml), предоставив метод getConfigLocations:

package org.bookguru;

import org.springframework.test.jpa.AbstractJpaTests;

public class BookInventorySystemTest extends AbstractJpaTests {

    private BookInventorySystem bookInventorySystem;

    public void setBookInventorySystem(
       BookInventorySystem bookInventorySystem) {
       this.bookInventorySystem = bookInventorySystem;
    }

    protected String[] getConfigLocations() {
       return new String[] {"/my/path/my-spring-config.xml"};
    }
} 

Итак, как вы запускаете свой код?

0 голосов
/ 05 апреля 2013

Стоит отметить следующее из Spring документации

@ EnableTransactionManagement и ищет @Transactional только для bean-компонентов в том же контексте приложения, в котором они определены. Это означает, что, если вы помещаете управляемую аннотацией конфигурацию в WebApplicationContext для DispatcherServlet, он проверяет только бины @Transactional в ваших контроллерах а не ваши услуги. См. Раздел 17.2, «DispatcherServlet» для получения дополнительной информации.

Когда вы используете портлеты, это означает, что вы должны включить транзакции, управляемые аннотациями, в контексте вашего портлета. Возможно, это ваша проблема.

Это поразило меня сегодня - у меня было приложение с несколькими портлетами, и я хотел настроить все компоненты базы данных в контексте приложения. Это было хорошо и работало во всех моих тестах.

Однако при развертывании в контейнере портлета ни один из моих bean-специфичных bean-компонентов не знал о транзакции - причина была в том, что мне не хватало в моем portletcontext. Ясно, как день, когда я прочитал руководство ....

0 голосов
/ 10 июня 2010

Чтобы класс был бобом, он должен быть:

  • либо отображается как <bean id=".." class="..">, либо аннотируется @Component, @Service или аналогичными аннотациями стереотипа
  • не , созданный вами. Если вы хотите, чтобы Spring связывал ваши зависимости, вы должны позволить ему создавать экземпляры ваших классов. Поэтому нет new GenericCrudServiceBean() (есть «хитрости» для включения внедрения зависимостей даже при использовании оператора new, но они предназначены для особых случаев)

Чтобы не создавать экземпляры ваших классов, вы должны поместить что-то «перед» вашими контроллерами и сервисами. Для веб-фреймворков это будет Servlet или дополнение к сервлету, которое обрабатывает ваши классы с помощью ApplicationContext пружины - в используется пружина MVC DispatcherServlet - в JSF используется нестандартная пружина ELResolver

В зависимости от вашей системы ищите «Интеграция пружин X».

Для вашего случая - портлеты - пружина имеет портлет MVC

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...