I know this question has been asked before however none of the solutions have worked for me.
I am trying to hit a controller to populate an index. The issue arises when I try and search the database for updates.
Here is are the classes I am dealing with:
Configuration:
@Configuration
@EnableTransactionManagement
public class WebApplication implements WebApplicationContextInitializer, ApplicationContextAware {
@Bean(name="dataSource")
public DataSource getDataSource() throws IOException {
InitialContext initialContext = new Context();
return (DataSource) initialContext.lookup("java:comp/env/jdbc/myDataSource");
}
@Bean(name="sessionFactory")
public SessionFactory getSessionFactory() throws IOException {
LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(getDataSource());
sessionBuilder.scanPackages(PropertyUtil.getInstance().getPropertySplitTrimmed("hibernate", "packagesToScan"));
sessionBuilder.addProperties(PropertyUtil.getInstance().getProperties("hibernate"));
return sessionBuilder.buildSessionFactory();
}
@Bean(name="transactionManager")
public HibernateTransactionManager transactionManager() throws IOException {
return new HibernateTransactionManager(getSessionFactory());
}
}
Controller:
@RestController
@Transactional
@RequestMapping("/persons")
public class IndexController {
@Autowired
PersonsDao personsDoa;
private ExecutorService executorService = Executors.newFixedThreadPool(100);
@RequestMapping(value="/index")
public void populateIndex(@DefaultValue("") @RequestParam String name){
...
...
List<Future<Persons>> holder = new ArrayList<>();
for(Persons p : people){
String name = p.name();
Future<Person> f = this.executorService.submit(new Callable<Person>(){
@Override
public Person call() throws Exception {
return personsDao.findByName(name); // <-- Throws error here
}
});
holder.add(f); // process the array later once all threads are finished
}
...
...
}
}
UPDATE: I've updated my Controller according to some suggestions, however I am still receiving the same error
Controller:
@RestController
@Transactional
@RequestMapping("/persons")
public class IndexController {
@Autowired
PersonsDao personsDoa;
private ExecutorService executorService = Executors.newFixedThreadPool(100);
@RequestMapping(value="/index")
public void populateIndex(@DefaultValue("") @RequestParam String name){
...
...
List<Future<Persons>> holder = new ArrayList<>();
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(sessionFactory.getCurrentSession())); //<-- THROWS ERROR HERE
for(Persons p : people){
String name = p.name();
Future<Person> f = this.executorService.submit(new Callable<Person>(){
SessionHolder holder = (SessionHolder)TransactionSynchronizationManager.getResources(sessionFactory);
Session session = holder.getSession();
@Override
public Person call() throws Exception {
Transaction t = session.getTransaction();
t.begin();
Persons p = personsDao.findByName(name);
t.commit();
session.flush();
return p;
}
});
holder.add(f); // process the array later once all threads are finished
}
...
...
}
}