0

so I have the following concerns.

Imagine I have 3 different Profile Entities (meant for different databases) in my application. They differ in some minor details for example.

Now I am creating a Spring Batch Job that will run once every 24h. and update the profile entities Status(ACTIF/INACTIF).

Each entity uses its own Repository(JPA). The logic to update a profile is similar to all profiles, it is based on an activation date. If the current date matches the activation date -> activate the profile. That is it.

Is it possible to create some kind of abstraction when creating the Reader, Processor and Writer? Currently I have 3 similar implementations right now and for example the Reader only differs in the DataSource provided and the Class to which the BeanRowMapper maps. The processors are one for each of the three types. And the writer only differs in the injected Repository to which I am saving the items.

I thought of introducing an Interface that all 3 Profiles implement and go from there, but is this possible and can you give me some tips on how to do it?

Here is some examples with the ItemReader for example:

public JdbcPagingItemReader<**MiProfile**> transportProfileReader() throws Exception {
        final var jdbcReader = "transportProfileReader";
        JdbcPagingItemReader<MiProfile> reader = new JdbcPagingItemReaderBuilder<MiProfile>().name(jdbcReader)
            .dataSource(**transportDataSource**)
            .fetchSize(100)
            .pageSize(1000)
            .beanRowMapper(**MiProfile.class**)
            .queryProvider(createQuery())
            // .parameterValues() -- use if you need query params
            .build();

        reader.afterPropertiesSet();
        return reader;
    }



public JdbcPagingItemReader<**Profile**> hospitalProfileReader() throws Exception {
        final var jdbcReader = "hospitalProfileReader";
        JdbcPagingItemReader<Profile> reader = new JdbcPagingItemReaderBuilder<Profile>().name(jdbcReader)
            .dataSource(**hospitalDataSource**)
            .fetchSize(100)
            .pageSize(1000)
            .beanRowMapper(**Profile.class**)
            .queryProvider(createQuery())
            // .parameterValues() -- use if you need query params
            .build();

        reader.afterPropertiesSet();
        return reader;
    }

I am fairly new to Spring Batch, so don't be too harsh :)

Thank you in advance!

abenci
  • 8,422
  • 19
  • 69
  • 134
tzvezdov
  • 13
  • 3
  • Similar isn't the same. If it really is the datasource just inject them into the method instead of calling a method (which is the recommended way anyway), the same for your row mapper. Don't call `afterPropertiesSet` Spring will do this for you. But if this is only for updating a status, why not just write a single query that does the update in one pass, instead of reading all entities, toggle true/false and write again. Just write a single update query and be done. Feels like an overkill for using Spring Batch for this. – M. Deinum Jun 26 '23 at 07:07
  • calling afterPropertiesSet() because I did not want to have 8 different Beans. Other than that I agree that a simple method in the Service to update all entries would be better. Spring Batch is an overkill for this task, but it's not me taking this decision.. Was it okay to not annotate all the different readers with @Bean and instead just call the afterPropertiesSet() ? – tzvezdov Jun 29 '23 at 14:26

1 Answers1

0

I just provided a JdbcPagingItemReaderBuilder method as BaseReader and only changed adjusted the .dataSource() on each ItemReader - at least it was less code.

I am calling the afterPropertiesSet() because I did not want to mark so many readers as Beans in my application context. Not sure if that is meaningful.

tzvezdov
  • 13
  • 3