Затмение с весны - PullRequest
       23

Затмение с весны

4 голосов
/ 29 октября 2010

Я использую Spring + EclipseLink 2 для управления сущностью в базе данных Derby. Выбор объекта из БД работает нормально, но когда я пытаюсь сохранить его, ничего не происходит. Программа выполняется правильно, и исключение не выдается. Я, вероятно, сделал что-то не так, так как я не знаком с Spring, спасибо за ваши комментарии и предложения:)

Метод ServerDaoDb: ​​

@Transactional
public void addServer(Server server) {
    EntityManager em = emf.createEntityManager();
    emf.createEntityManager().persist(server);
    em.close();
}

Контекст приложения:

 ... 
 <tx:annotation-driven />

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="SpringPratiquePU" />
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean 
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

Persistence.xml:

  <persistence-unit name="SpringPratiquePU" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>net.athom.spring.examples.models.eas.Server</class>
    <class>net.athom.spring.examples.models.eas.Node</class>
    <properties>
      <property name="eclipselink.target-database" value="DERBY"/>
      <property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/SpringPratique"/>
      <property name="javax.persistence.jdbc.password" value="clem"/>
      <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
      <property name="javax.persistence.jdbc.user" value="clem"/>
    </properties>
  </persistence-unit>
</persistence>

Трасса отладки:

DEBUG JpaTransactionManager:365 - Creating new transaction with name [net.athom.spring.examples.service.impl.ServerManagerImpl.addServer]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
[EL Info]: 2010-10-29 15:33:27.443--ServerSession(14894886)--EclipseLink, version: Eclipse Persistence Services - 2.0.2.v20100323-r6872
[EL Info]: 2010-10-29 15:33:28.606--ServerSession(14894886)--file:/C:/netbeanProject/SpringPratique/src/_SpringPratiquePU login successful
15:33:28,893       DEBUG JpaTransactionManager:323 - Opened new EntityManager [org.eclipse.persistence.internal.jpa.EntityManagerImpl@1779885] for JPA transaction
15:33:28,951       DEBUG DefaultListableBeanFactory:242 - Returning cached instance of singleton bean 'transactionManager'
15:33:28,952       DEBUG JpaTransactionManager:286 - Found thread-bound EntityManager [org.eclipse.persistence.internal.jpa.EntityManagerImpl@1779885] for JPA transaction
15:33:28,953       DEBUG JpaTransactionManager:470 - Participating in existing transaction
15:33:29,266       DEBUG JpaTransactionManager:752 - Initiating transaction commit
15:33:29,267       DEBUG JpaTransactionManager:462 - Committing JPA transaction on EntityManager [org.eclipse.persistence.internal.jpa.EntityManagerImpl@1779885]
15:33:29,268       DEBUG JpaTransactionManager:548 - Closing JPA EntityManager [org.eclipse.persistence.internal.jpa.EntityManagerImpl@1779885] after transaction
15:33:29,308       DEBUG EntityManagerFactoryUtils:328 - Closing JPA EntityManager

Ответы [ 3 ]

3 голосов
/ 29 октября 2010

Я не уверен, что именно не так с вашей конфигурацией (я думаю, EntityManager, созданный вручную, не может участвовать в @Transactional транзакциях), но типичная конфигурация JPA в Spring выглядит следующим образом, поэтому вам не нужнодля создания EntityManager вручную (также обратите внимание на имя класса фабричного компонента):

@PersistenceContext
private EntityManager em;

@Transactional  
public void addServer(Server server) {  
    em.persist(server);  
} 

<bean id="entityManagerFactory"   
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">   
    <property name="persistenceUnitName" value="SpringPratiquePU" />   
</bean>
3 голосов
/ 30 октября 2010

Спасибо за ваши ответы, оба были очень полезны.Я закончил тем, что использовал LocalContainerEntityManagerFactoryBean, чтобы я мог внедрить менеджер сущностей в свой дао.Я добавил servlet-agent-2.5.6.jar в папку lib и передал опции VM: -javaagent: путь / к / lib / ervlet-agent-2.5.6.jar

Затем я изменил ApplicationContext.xml:

 <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="SpringPratiquePU" />
         <property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
    </property>
    </bean>

И мой дао: ...

  @PersistenceContext
  private EntityManager em;


   @Transactional
   public void addServer(Server server) {
       em.persist(server);
   }

Стойкость и транзакции теперь работают как шарм!

3 голосов
/ 29 октября 2010

Ваша ошибка здесь:

@Transactional
public void addServer(Server server) {
    EntityManager em = emf.createEntityManager();
    emf.createEntityManager().persist(server);
    em.close();
}

Вы создаете два разных экземпляра EntityManager, em, который вы закрываете, и новый на следующей строке с emf.createEntityManager(), который вы используете непосредственно для сохранения ваших изменений.

Попробуйте это:

@Transactional
public void addServer(Server server) {
    EntityManager em = emf.createEntityManager();
    em.persist(server);
    em.close();
}

Полагаю, что когда вы закрываете свой экземпляр em, ваши изменения записываются в БД, но, если это не так, вы должны добавить em.flush(); непосредственно перед закрытием экземпляра em.

...