2017-02-15 22 views
1

Я могу сохранить новые данные, но я не могу делать обновления. Ошибок нет, только никаких транзакций, совершающих изменения. Я предполагаю, что это связано с тем, как я организовал транзакции. Я пробую кучу относительно новых (для меня) наборов технологий. Ниже приведены подробности.EntityManager.merge() не совершается (Wildfly, JPA, JTA)

Я использую следующие инструменты/технологии:

  • Wildfly 8 и Java 7 (что мой хостинг использует)
  • аннотаций, с минимальным XML является целью предлагается
  • Struts 2.3 (с помощью конференц-плагина)
  • Пружины 3.2
  • Hibernate 4.3
  • ССТА (с контейнерными управляемыми операциями (СМТ))
  • JPA 2 (с контейнером Managed Persistence Context)
  • EJBs (У меня есть приложение удаленного клиента, который работает HtmlUnit тесты)
  • Три файлы WAR и файл JAR один EJB развернут
  • SpringBeanAutowiringInterceptor к autowire в EJBs (может ли быть ошибка здесь, где операции не совершают?)

beanRefContext.xml (требуется SpringBeanAutowiringInterceptor)

<beans> 
    <bean 
    class="org.springframework.context.support.ClassPathXmlApplicationContext"> 
    <constructor-arg value="classpath:campaignerContext.xml" /> 
    </bean> 
</beans> 

campaignerContext.xml

<beans> 
    <context:component-scan base-package="..." /> 
    <jee:jndi-lookup id="dataSource" jndi-name="jdbc/CampaignerDS"/> 
    <tx:annotation-driven/> 
    <tx:jta-transaction-manager/> 
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="persistenceUnitName" value="campaigner" /> 
    </bean> 
    <bean id="ehCacheManager" class="net.sf.ehcache.CacheManager" factory-method="create"> 
    <constructor-arg type="java.net.URL" value="classpath:/campaigner_ehcache.xml"/> 
    </bean> 
</beans> 

persistence.xml

<persistence> 
    <persistence-unit name="campaigner" transaction-type="JTA"> 
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> 
    <jta-data-source>java:/jdbc/CampaignerDS</jta-data-source> 

    <class>....UserRegistration</class> 
    ... 

    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode> 

    <properties> 
     <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" /> 
    </properties> 
    </persistence-unit> 
</persistence> 

SecurityServiceBean.java

@EnableTransactionManagement 
@TransactionManagement(value = TransactionManagementType.CONTAINER) 
@TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW) 
@Stateless 
@Interceptors(SpringBeanAutowiringInterceptor.class) 
@DeclareRoles("Security Admin") 
public class SecurityServiceBean extends AbstractCampaignerServiceImpl implements 
    SecurityServiceLocal, SecurityServiceRemote 
{ 
    @Override 
    @PermitAll 
    @Transactional(propagation = Propagation.REQUIRES_NEW) 
    public UserRegistration confirmRegistration(
    String confirmationCode) throws ApplicationException 
    { 
     UserRegistration userRegistration = this.userRegistrationDAO 
     .find(new UserRegistrationQuery(null, confirmationCode)).uniqueResult(); // Should be attached now 

    ... 
      userRegistration.setConfirmationDate(new Date()); 
      userRegistration.setState(State.CONFIRMED); 
      userRegistration = this.userRegistrationDAO.saveOrUpdate(userRegistration); 
    ... 
    } 
} 

UserRegistrationDAO.java

@Override 
public UserRegistration saveOrUpdate(
    UserRegistration obj) throws DAOException 
{ 
    log.debug("[saveOrUpdate] isJoinedToTransaction? " 
      + (this.em.isJoinedToTransaction() ? "Y " : "N")); 

    try 
    { 
    if (obj.getId() == null) 
    { 
     this.em.persist(obj); 

     log.debug("[saveOrUpdate] called persist()"); 

     return obj; 
    } 
    else 
    { 
     UserRegistration attached = this.em.merge(obj); 

     log.debug("[saveOrUpdate] called merge()"); 

     return attached; 
    } 
    } 
    catch (PersistenceException e) 
    { 
    throw new DAOException("[saveOrUpdate] obj=" + obj.toString() + ",msg=" + e.getMessage(), e); 
    } 
} 

Есть ли какие-либо настройки в standalone.xml Wildfly, которые вам нужно увидеть или что я должен установить?

BTW, это невероятно раздражает и расстраивает. Это должна быть простая одноразовая настройка, которую я могу сделать, а затем забываю о том, когда я перехожу к созданию своего веб-сайта, который должен быть там, где большая часть моего времени потрачена. Отсутствие полной документации в любом месте УДИВИТЕЛЬНО. Сейчас развитие было остановлено, пока это не будет решено /RANT

ОБНОВЛЕНИЯ

  • Я попытался переключиться на источник данных XA, так как некоторые сайты утверждали, что было необходимо, но это не сработало (А не было Думаю так, но должен был попробовать). Также попытался настроить emf с dataSource вместо persistenceUnitName, как некоторые другие сайты. Нет радости.
  • Я попытался заменить TransactionManager с JpaTransactionManager, но это только привело к этому исключение: JTA EntityManager не может использовать getTransaction()
+0

'@ EnableTransactionManagement' здесь практически бесполезен, он работает только на' @Configuration 'аннотированные классы (и у вас уже есть' '. Поскольку вы используете EJB, вы также должны позаботиться о том, чтобы использовать правильную аннотацию' @ Transactional', иначе контейнер не начнет транзакцию, и будет весной, так как EJB не управляется весной. –

+0

Спасибо за информацию. Когда вы произнесете «правильную аннотацию @Transactional», что вы имеете в виду? Вы говорите об атрибуте распространения? –

+1

Нет, что вы используете правильный, вы не должны использовать весеннюю версию, но версию EJB. –

ответ

0

Ответ, благодаря М. Deinum, что я использовал неправильный @ транзакционный. Я должен был использовать javax.transaction.Transactional, но вместо этого использовал Spring. Обратите внимание, что правильный будет выглядеть как «@Transactional (TxType.REQUIRES_NEW)» вместо «@Transactional (распространение = Propagation.REQUIRES_NEW)»

Смежные вопросы