2

I have one dummy question. To explain my use-case, I have different type of DAOs; say Users, Beers... etc. I wanted to use one generic ItemWriter for all of them. I created a CommonComponentConfiguration where I defined;

@Bean
@Qualifier(WRITER_INSERT_TO_DATABASE_BEAN)
public ItemWriter<?> insertDbItemWriter(@Qualifier(DATA_SOURCE) DataSource dataSource,
                                        @Qualifier("insertSql") String insertSql) {
         return new MyItemWriter<>(dataSource, insertSql);
     }

The writer class goes like this;

@Slf4j
public class MyItemWriter<T> extends JdbcBatchItemWriter<T> {

    public MyItemWriter(DataSource dataSource, String sql) {
        this.setDataSource(dataSource);
        this.setSql(sql);
        this.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
        this.setAssertUpdates(false);
    }

    @Override
    public void write(List<? extends T> items) {
        try {
            super.write(items);
        } catch (Exception e) {
            log.error("Could not write the items " + items);
            log.error(e.getMessage());
        }
    }
}

So far everything is okay. Where things gets complicated is, I have seperate configuration classes for each repository where I define repository specific items. For instance the step for inserting to DB for Users.

@Bean
@Qualifier(STEP_INSERT_TO_DB_BEAN)
public Step insertToDbStep(@Qualifier(READER_LOADED_INPUT_DATA_BEAN) ListItemReader<User> sourceItemReader, UserInsertProcessor userInsertProcessor, @Qualifier(WRITER_INSERT_TO_DATABASE_BEAN)
        ItemWriter<User> dbItemWriter) {
    return stepBuilderFactory.get("processInsertStep").<User, User>chunk(100)
            .reader(sourceItemReader)
            .processor(userInsertProcessor)
            .writer(dbItemWriter)
            .build();
}

When I write this code in IJ is complaining Could not autowire. Qualified bean must be of 'ItemWriter<User>' type. , but heavens sake when I execute the code, it works, and does what its supposed to do. When I debug, it binds the right thing.

Well, you may say, if it works don't touch it. However I really want to know what's happening behind the curtains.

Also, if you see a flaw in the design (such as trying to use one common thing for everything), your suggestions are more than welcomed.

Thank you in advance.

PS: Seen this thread below, looks like very similar -if not the same- case. However I would like to know if there's something to do with the generics here. IntelliJ IDEA shows errors when using Spring's @Autowired annotation

Edit: Error

Kyrstellaine
  • 441
  • 5
  • 16
Bleach
  • 309
  • 3
  • 18
  • what is `IJ`? and what does _complaining_ mean? does not compile? it is a warning? etc – Eugene Apr 20 '21 at 20:42
  • Sorry, Intellij. – Bleach Apr 20 '21 at 20:45
  • and the second part of my question? – Eugene Apr 20 '21 at 20:47
  • Oh, attached to the question(had to paint some stuff on it though.) – Bleach Apr 20 '21 at 20:53
  • 1
    that looks like a warning, sorry, I still can't figure out if your project does not _compile_ in intellij because of that – Eugene Apr 20 '21 at 20:56
  • It does compile. It runs, and does what its supposed to do. However when I get a "warning" like this, there usually is a problem and it fails in runtime. However this time it does not. It's just I want to know what I am doing, and whether it's right use case using > in this case... – Bleach Apr 20 '21 at 20:58
  • 2
    It is an intellij "thing", nothing to worry about. It is just how their static analysis for these kind of things has been written. I get the same kind of warnings in our project when we return a `ResponseEntity>` from `@ExceptionHandler`s... In general returning a wildcard to the callers is a big code smell, since now the callers are stuck with them and need to cast all the time. I really think that in this case - you are good. – Eugene Apr 20 '21 at 21:07
  • Hearing that is a big relief. Thank you. – Bleach Apr 20 '21 at 21:09

1 Answers1

0

However I really want to know what's happening behind the curtains.

For this IntelliJ IDEA warning, you are right that it is the same issue discussed in IntelliJ IDEA shows errors when using Spring's @Autowired annotation (and also as explained by Eugene in comments)

Also, if you see a flaw in the design (such as trying to use one common thing for everything), your suggestions are more than welcomed.

If the current approach works for you, you can use it. However, I would recommend making one thing do one thing and do it well. In your case, this would be using an item writer for each domain type and wrap those writers in a ClassifierCompositeItemWriter. The composite writer uses a Classifier to classify items and call the corresponding writer accordingly.

Mahmoud Ben Hassine
  • 28,519
  • 3
  • 32
  • 50
  • 1
    Appreciate the answer. My flaw in the design is that I have 2 types of writers. One for Delete, one for Insert. If i use wrapper classes, Ill have something like `UserDeleteWriter` `UserInsertWriter` `BeerDeleteWriter` `BeerInsertWriter` and the list goes on. It gets so big.Either I did make a mistake somewhere else thus I ended up here, or this is normal in Spring. (which I don't think so.) – Bleach Apr 21 '21 at 08:29