0

I've a job with one Step. The step has the usual setup.

  1. reader: read from a Stock DB-table "instrument"
  2. processor: retrieving the latest price from an external service
  3. writer: writing the latest price in the price DB-table "instrumentprice"

There is a ItemWriteListener which does some calculations on the latest price in db-table "instrumentprice". So, it's important that the writer is persisting the latest price immediately in the DB-table "instrumentprice"

In the writer the methods, persist and flush are called on the EntityManager for the Entity "instrumentprice". But Hibernate doesn't write into the table "instrumentprice" immediately. It does write into the table "instrumentprice" at a later stage, but I haven't figured out the mechanism yet.

@Configuration
@ComponentScan(basePackages = {"com.chartinvestbatch.alphaVantageHistory"})
public class JobConfig {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    
    @Autowired
    private ChartInvestJobListener chartInvestJobListener;

    @Bean
    public Job jobAlphaVantage(@Qualifier("stepProcessingPrices") Step stepProcessingPrices) throws IOException {
        return jobBuilderFactory
                .get("JobAlphaVantage")
                .listener(chartInvestJobListener)
                .incrementer(new RunIdIncrementer())
                .start(stepProcessingPrices)
                .build();
    }

}


@Configuration
public class StepConfig {
    
    @Autowired
    private StepBuilderFactory stepBuilderFactory;
    
    @Autowired
    private TaCalcListener taCalcListener;
    
    @Bean
    @Qualifier("stepProcessingPrices")
    public Step stepProcessingPrices(HibernateCursorItemReader<Instrument> hibernateCursorItemReader, ItemProcessor<Instrument, InstrumentAndPricesDto> itemProcessor,  ItemWriter<InstrumentAndPricesDto> itemWriter) throws IOException {
        return stepBuilderFactory
                .get("stepProcessingPrices")
                .<Instrument, InstrumentAndPricesDto>chunk(1)
                .listener((ItemWriteListener<InstrumentAndPricesDto>) taCalcListener)
                .reader(hibernateCursorItemReader)
                .processor(itemProcessor)
                .writer(itemWriter)
                .build();
    }
    
}


@Scope(value = "step")
@Component
@Transactional
public class StockItemWriter implements ItemWriter<InstrumentAndPricesDto> {

    static Logger log = LogManager.getLogger(StockItemWriter.class);

    @Autowired
    private IntrumentPriceDao intrumentPriceDao;

    @Override
    public void write(List<? extends InstrumentAndPricesDto> instrumentAndPricesDtoList) throws Exception {

        for (InstrumentAndPricesDto dto : instrumentAndPricesDtoList) {
        
            // check some stuff etc ....

            InstrumentPrice instrumentPrice = new InstrumentPrice();
            instrumentPrice.setDate(dto.getDate());
            ...

            intrumentPriceDao.persist(instrumentPrice);
            intrumentPriceDao.flush();
        }
    }

}



@Transactional(propagation = Propagation.MANDATORY)
public abstract class GenericDao<T> {

    @PersistenceContext
    protected EntityManager entityManager;

    public EntityManager getEntityManager() {
        return entityManager;
    }

    public T persist(final T t) {
        entityManager.persist(t);
        return t;
    }


    public void flush() {
        entityManager.flush();
    }
}


@Repository
@Transactional(propagation = Propagation.MANDATORY)
public class IntrumentPriceDao extends GenericDao<InstrumentPrice> {

}
Squashman
  • 13,649
  • 5
  • 27
  • 36
user2023141
  • 895
  • 5
  • 17
  • 36
  • How do you determine **Hibernate doesn't write into the table "instrumentprice" immediately**? Flush only synchronize the state of current db session with database, and you only see actual changes in other db session after commit. – samabcde Nov 09 '20 at 04:44
  • I've put a breakpoint in the listener class, then I checked what is written in the DB, and the latest price was not persisted in the DB. – user2023141 Nov 09 '20 at 07:16
  • as @samabcde you have to differentiate between *persist*, *flush* and *commit*. Check this for a similar problem https://stackoverflow.com/questions/64693836/want-to-save-data-into-table-in-database-immediately/64696713#64696713 – Aman Nov 09 '20 at 12:05
  • I tied everything ....with/without @Transaction annotation , persist , flush. None had any effect. What I found out is that the Entity is persisted as soon as the listener (ItemWriterListener) is finished. So, it's the listener which is prohibiting the entity to be persisted. – user2023141 Nov 09 '20 at 19:20

0 Answers0