I have following architecture:
Abstract Controller:
public abstract class AbstractController<E> {
private final AbstractService<E> abstractService;
public AbstractController(AbstractService<E> abstractService) {
this.abstractService = abstractService;
}
@PostMapping("blabla")
public List<Something> getList(@RequestBody whatever) {
return abstractService.method(whatever);
}
}
Abstract Service:
public abstract class AbstractService<E> {
@Autowired
private SomeConcreteRepository concreteRepository;
private final EntityTypeAwareRepository<E> entityRepository;
@Autowired(required = false)
public AbstractService(EntityTypeAwareRepository<E> entityRepository) {
this.entityRepository = entityRepository;
}
List<Something> method() {
String tableName = extractTableName(this.entityRepository.getEntityClass());
return this.concreteRepository.someJdbcCall(tableName);
}
}
Entity A Repository:
@Repository
public interface EntityARepository extends EntityTypeAwareRepository<A>, JpaRepository<A, Long>, JdbcRepository {
// JdbcRepository has implementation for A entity and its methods are called with EntityARepository in service layer
}
Entity A Controller:
@RestController
@RequestMapping("base/mapping")
public class AController extends AbstractController<A> {
private final AService aService;
@Autowired
public AController(AService aService) {
super(aService);
this.aService = aService;
}
// concrete endpoints methods
}
Entity A Service:
@Service
@PreAuthorize(someRole)
@Transactional
public class AService extends AbstractService<A> {
private final ARepository aRepository;
@Autowired
public AService(ARepository aRepository) {
super(aRepository);
this.aRepository = aRepository;
}
//methods using Spring-JPA aRepository methods
//and
//methods using JdbcRepository interface implementation (via same reference)
}
And it is scaled for any entity you like. EntityTypeAwareRepository
is NoBeanRepository
with defualt method for finding concrete repository entity. To the point. Abstract controller is getting calls from client for different kind of entities but regarding the same thing. So the goal is that one abstract controller will handle calls for N sub-controllers.
SomeConcreteRepository
is concrete class handling this logic.
The problem is that it is not autowiring, together with entityRepository
in abstract service. causing NPE. Actually the latter is passed from sub-controller but resolves to null.
And in fact in this configuration I had it working somehow, but next day autowiring was not working properly. So I am not sure if there is some problem with this architecture or I just had some building problems that it magically worked. Do you have idea what can cause problem? Can it be connected with proxies from @Transactional?
I am sure everything is properly scanned and all beans are visible.