I need to override the default save methods of SimpleJPaRepository. However I ran into an issue with generics and the fact that the save methods use <S extends T> as return type instead of just T.
Here the overridden method:
Compiler error:Code:public class ChemicalStructureRepositoryImpl<T extends ChemicalStructure> extends QueryDslJpaRepository<T, Long> implements ChemicalStructureRepository<T> { //... @Override @Transactional public <S extends T> S save(S structure) { QChemicalStructure qStructure = QChemicalStructure.chemicalStructure; //querydsl BooleanExpression hasSameSructureKey = qStructure.structureKey.eq(structure.getStructureKey()); T result = super.findOne(hasSameSructureKey); if (result == null) { structure.reset(); em.persist(structure); return structure; } else { return super.save(result); // compiler error } }
First what I want to achieve with this: A ChemicalStructure is immutable. It's data can't change. So let's say user loads entity with id 1 and changes it's data. the entity with id one must stay the same. So therefore I check using unique "Business key" whether an entity identical to the changed with id 1 exist. If yes, use that one, if no create a new one.incompatible types
required: S
found: T
where T,S are type-variables:
T extends ChemicalStructure declared in class ChemicalStructureRepositoryImpl
S extends T declared in method <S>save(S)
I created the reset method because just calling new T(args) won't work as it will have type T instead of S. reset sets id = null and any metadata fields (created, modified,...).
however as you can see I still get compiler error when calling em.merge as also here T is returned instead of S. The only solution is see is to manually cast to S and make a doc comment you should only use T or else exception. But that seems extremely ugly?
I could just leave it be and do the logic in a service layer? Problem is that it then can very easily be circumvented which is problematic. Example: You have a boxes of tools. Now you realize that in one box at a certain space you accidentally entered a hammer instead of a screwdriver into the system. Now you change the hammer to a screwdriver. But of course you don't want the actual hammer entity to become a screwdriver and hence all boxes using a hammer now contain a screwdriver. I want to do exactly what I outlined above.
Alternative suggestion? What am I missing or how else can I override save?


Reply With Quote