Java >> Java tutorial >  >> Tag >> synchronized

HibernateException:Kunne ikke hente transaktionssynkroniseret session for den aktuelle tråd

Når jeg ser på din log, kan jeg med det samme se, at dine transaktionsindstillinger er forkert indstillet. Det er fordi der ikke er nogen TransactionInterceptor indkald din staksporing.

TransactionInterceptor kaldes af dine Spring Service-proxyer, når dine webcontrollere kalder de faktiske Service-metoder.

  1. Sørg for at bruge Spring hibernate4 klasserne:

    org.springframework.orm.hibernate4.HibernateTransactionManager
    
  2. Tilsidesæt ikke @Transactional metoder, men brug en skabelon mønstre i stedet.

  3. Prøv at bruge JPATransactionManager i stedet, så du kan injicere den nuværende EntityManager med @PersistenceContext anmærkning i stedet for. Dette er meget mere elegant end at kalde sessionFactory.getCurrentSession() i hver DAO-metode.


Én

Du skal bruge @Transactional for @Service og @Repository . Det lader Spring ansøge og oprette fuldmagter med Transaktionssupport.

I din kode din @Service klasse har ingen @Transacional enten på klasseniveau eller metodeniveau

Anden

Hvor er klassen, der implementerer WebApplicationInitializer ?Jeg kan se, at du forlænger en klasse.. Min pointe er alligevel, hvor er noget i stil med følgende:

@Override
public void onStartup(ServletContext container) {
    // Create the 'root' Spring application context
    AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
    rootContext.register(CentralServerConfigurationEntryPoint.class);

    // Manage the lifecycle of the root application context
    container.addListener(new ContextLoaderListener(rootContext));

    // Create the dispatcher servlet's Spring application context
    AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
    dispatcherServlet.register(CentralWebConfigurationEntryPoint.class);

    // Register and map the dispatcher servlet
    ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherServlet));
    dispatcher.setLoadOnStartup(1);
    dispatcher.addMapping("/");

}

Hvor CentralServerConfigurationEntryPoint.class må kun scanne komponenter, der skal fungere på serversiden (@Service , @Repository , @Configuration til Transaktion, Hibernate, DataSource osv.)

Hvor CentralWebConfigurationEntryPoint må kun scanne komponenter, der skal fungere i klienten/websiden (@Controller , @Configuration til formatere, fliser, konvertere osv.)

Jeg forstår ikke din kode om

@Override
protected WebApplicationContext createRootApplicationContext() {
    AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();

    ConfigurableEnvironment environment = rootContext.getEnvironment();
    environment.setDefaultProfiles("production");

    PropertyUtil propertyUtil = PropertyUtil.getInstance(environment.getActiveProfiles());
    String[] basePackages = propertyUtil.getPropertySplitTrimmed("webapp", "basePackages");
    rootContext.scan(basePackages);

    return rootContext;
}

@Override
protected WebApplicationContext createServletApplicationContext() {
    return new AnnotationConfigWebApplicationContext();
}

Min pointe er:du skal har to AnnotationConfigWebApplicationContext en til serveren og web-siden.


Meget kort svar på dette spørgsmål-id, du skal bare bruge @Transactional med din dao-klasse, markere din konfigurationsklasse som @EnableTransactionManagement og oprette en bean

**@Bean
public PlatformTransactionManager transactionManager() {
    DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource());
    return transactionManager;
}**

Her, hvis du ser kodeeksemplet tilgængeligt i EnableTransactionManagement-annotering, foreslår det, at du bruger DataSourceTransactionManager i stedet for HibernateTransactionManager.


Java tag