使用@EnableTransactionManagement当前没有事务处于活动状态

时间:2013-09-03 08:19:17

标签: java spring spring-data

首先是stacktrace:

org.springframework.dao.InvalidDataAccessApiUsageException: 
Exception Description: No transaction is currently active; nested exception is javax.persistence.TransactionRequiredException: 
Exception Description: No transaction is currently active
    org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:316)
    org.springframework.orm.jpa.DefaultJpaDialect.translateExceptionIfPossible(DefaultJpaDialect.java:121)
    org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:403)
    org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58)
    org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
    org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    org.springframework.data.jpa.repository.support.LockModeRepositoryPostProcessor$LockModePopulatingMethodIntercceptor.invoke(LockModeRepositoryPostProcessor.java:92)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    com.sun.proxy.$Proxy299.saveAndFlush(Unknown Source)

我很确定这是一个愚蠢的错误,但我似乎无法找到我做错的事情:

@Service

@Service
public class BookInfoTracker implements InfoTracker
{

  @Autowired
  @Qualifier("bookTrackerRepository")
  private TrackerRepository bookTrackerRepository;

  public BookInfoTracker() {}

  public BookInfoTracker (TrackerRepository bookTrackerRepository)
  {
    this.bookTrackerRepository = bookTrackerRepository;
  }

  @Transactional
  @Override
  public void track (long idBooking, String idLeg, String bookingEmail, int sequence, String event)
  {
    BookInfo ci = new BookInfo(idBooking, idLeg, bookingEmail, new Date(), sequence, event);

    bookTrackerRepository.saveAndFlush(ci);
  }

  @Override
  public int getSequenceFrom (long idBooking, String idLeg)
  {
    BookInfo tracked = findLastTrackedBookFrom(bookTrackerRepository.getLastTrackedBookByIdBookingAndIdLeg(idBooking, idLeg));
    return null == tracked? 0 : tracked.getSequence()+1;
  }

  private BookInfo findLastTrackedBookFrom (List<BookInfo> trackedBooks)
  {
    return trackedBooks.isEmpty() ? null : trackedBooks.get(0);
  }
}

jpa配置有一个基类:

@EnableLoadTimeWeaving(aspectjWeaving=AspectJWeaving.ENABLED)
public abstract class JpaConfiguration
{

  public JpaConfiguration ()
  {
    super();
  }

  public abstract LocalContainerEntityManagerFactoryBean buildEntityManagerFactory () throws SQLException;

  @Bean(name = "transactionManager")
  public PlatformTransactionManager buildTransactionManager () throws SQLException
  {
    JpaTransactionManager manager = new JpaTransactionManager();
    LocalContainerEntityManagerFactoryBean factory = buildEntityManagerFactory();
    manager.setEntityManagerFactory(factory.getObject());

    return manager;
  }

  protected Database toDatabase (String databaseProductName)
  {

    for (Database database : Database.values())
      if (databaseProductName.equalsIgnoreCase(database.toString())) return database;

    return null;
  }

  protected LocalContainerEntityManagerFactoryBean initializeFactory (DataSource datasource, String persistenceUnitName, String... packagesToScan) throws SQLException
  {
    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();

    factory.setDataSource(datasource);

    factory.setPersistenceUnitName(persistenceUnitName);
    factory.setPackagesToScan(packagesToScan);


    EclipseLinkJpaVendorAdapter jpaAdaptor = new EclipseLinkJpaVendorAdapter();


 jpaAdaptor.setDatabase(toDatabase(datasource.getConnection().getMetaData().getDatabaseProductName()));
    jpaAdaptor.setShowSql(true);
    factory.setJpaVendorAdapter(jpaAdaptor);

    Properties jpaProperties = new Properties();
    jpaProperties.put("eclipselink.ddl-generation", "none");
    jpaProperties.put("eclipselink.ddl-generation.output-mode", "database");
    jpaProperties.put("eclipselink.logging.level.sql", "FINE");
    jpaProperties.put("eclipselink.logging.parameters", "true");
    jpaProperties.put("eclipselink.cache.shared.default", "false");
    jpaProperties.put("eclipselink.target-database", "MySQL");
    jpaProperties.put("eclipselink.weaving","false");
    factory.setJpaProperties(jpaProperties);

    factory.afterPropertiesSet();
    return factory;
  }
}

然后是具体配置,子类:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.book.tracking.repositories"}, entityManagerFactoryRef="bookManagerFactory")
@Profile({"integration","test","release"})
public class JpaBookConfiguration extends JpaConfiguration
{
  @Autowired
  @Qualifier("bookDs")
  private DataSource datasource;

  @Override
  @Bean(name = "bookManagerFactory")
  public LocalContainerEntityManagerFactoryBean buildEntityManagerFactory () throws SQLException
  {
    return initializeFactory(datasource, "book.jpa", "com.book.tracking.entity");
  }
}

然后是restservice:

@Controller
@ControllerAdvice
@RequestMapping("/bookservice")
public class BookRestService implements IBookService
{
  private static final String LEG_VALID_PATTERN = "^(20)\\d\\d(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])_[A-Z]{3}-[A-Z]{3}$";

  @Autowired
  @Qualifier("bookBuilder")
  private IBookBuilder bookBuilder;
  @Autowired
  @Qualifier("bookInfoTracker")
  private InfoTracker bookInfoTracker;
  @Autowired
  @Qualifier("bookBookingEventsGenerator")
  private BookingEventsGenerator bookBookingEventsGenerator;

  public BookRestService (IBookBuilder bookBuilder, 
      InfoTracker infoTracker, BookingEventsGenerator bookBookingEventsGenerator)
  {
    this.bookBookingEventsGenerator = bookBookingEventsGenerator;
    this.bookBuilder = bookBuilder;
    this.bookInfoTracker = infoTracker;
  }

  public BookRestService ()
  {
  }

  @Override
  @RequestMapping(value="/generate/{idBooking}/{idLeg}")
  public ResponseEntity<String> generateOneWayEvent (@PathVariable("idBooking") final long idBooking, @PathVariable("idLeg") final String idLeg)
  {
    return executeEventCommand(new EventCommand() {
      @Override
      public BookingEvent execute() {
        BookingEvent event = bookBookingEventsGenerator.generateEventFrom(idBooking, idLeg);
        return event;
      }
    }, idBooking, idLeg, "PUBLISH");
  }


  private ResponseEntity<String> executeEventCommand (EventCommand eventCommand, long idBooking, String idLeg, String operation)
  {
    try {
      validate(idLeg);
      logFor(idBooking, idLeg, "generateOneWayEvent");
      HttpHeaders headers = modifyResponseAccordingTo(idLeg);


      BookingEvent event = eventCommand.execute();
      int sequence = bookInfoTracker.getSequenceFrom(idBooking, event.getBookingIdentifier());
      String bookIcs = generateBookFrom(event, sequence);
      logger.debug(bookInfoTracker.getClass());
      //exception here      
      bookInfoTracker.track(idBooking, event.getBookingIdentifier(), bookBookingEventsGenerator.getContactEmail(), sequence, operation);

      return new ResponseEntity<String>(bookIcs, headers, HttpStatus.OK );
    } catch(LegNotFoundException lnfe){
      logger.error(lnfe);
      return new ResponseEntity<String>("Something went wrong", HttpStatus.NOT_FOUND);
    }
  }

 /** other methods **/

}

好像不考虑@Transactional注释?但是我使用了@EnableTransactionManagement。你能在我的配置中看到错误吗?

更新:

@Configuration
@Profile({"integration", "release"})
public class IBookSpringConfiguration
{

  @Autowired
  @Qualifier("bookRestService")
  private IBookService bookRestService;

  @Autowired
  @Qualifier("bookTrackerRepository")
  private TrackerRepository bookTrackerRepository;

  public ReloadableResourceBundleMessageSource getMessageBundle(){
    ReloadableResourceBundleMessageSource bundle = new ReloadableResourceBundleMessageSource();
    bundle.setBasename("book-message");
    return bundle;
  }

  @Bean(name = "bookInfoTracker")
  public InfoTracker getBookTrackingService(){
    return new BookInfoTracker(bookTrackerRepository);
  }

  @Bean(name = "bookBuilder")
  public IBookBuilder getBookBookingService(){
    return new BookBuilder(getMessageBundle());
  }

  @Bean(name = "i18n")
  public I18nUtilACL getI18n(){
    return new I18nUtilBook(MultiSourceSiteCustomizer.getInstance());
  }

  @Bean(name = "bookBookingEventsGenerator")
  public BookingEventsGenerator getBookBookingEventsGenerator(){
    return new BookEventsGenerator();
  }

  @Bean(name = "bookBookingLegFactory")
  public BookingLegEventsGenerator getBookBookingLegFactory(){
    return new BookBookingLegEventsGenerator();
  }

  @Bean(name = "bookBookingFlightEventsGenerator")
  public BookingEventsGenerator getBookBookingFlightEventsGenerator(){
    return new BookEventsGenerator();
  }

  @Bean(name = "bookRestService")
  @Scope("singleton")
  public IBookService getBookRestService ()
  {
    return new BookRestService();
  }
}

已解决,但不知道为什么:

我只是在JpaBookConfiguration中合并JpaConfiguration的父类和子类。现在它正在运作。不知道为什么。你可以解释吗?

0 个答案:

没有答案