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.
-
Sørg for at bruge Spring hibernate4 klasserne:
org.springframework.orm.hibernate4.HibernateTransactionManager
-
Tilsidesæt ikke
@Transactional
metoder, men brug en skabelon mønstre i stedet. -
Prøv at bruge
JPATransactionManager
i stedet, så du kan injicere den nuværendeEntityManager
med@PersistenceContext
anmærkning i stedet for. Dette er meget mere elegant end at kaldesessionFactory.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.