I'm using Spring Boot with JPA / Hibernate and I'm trying to decouple the business layer from the data layer. I would like to be able to (relatively easily) switch from a relational database to a rdf triple store.
Here is a partial simplified description of my current try. I have entities such as:
@Entity(name="Drawer")
public class DrawerEntity {
@Id
private int id;
private String label;
public int getId(){return id;}
public void setId(int id){this.id=id;}
public String getLabel(){return label;}
public void setLabel(String label){this.label=label;}
}
I have business objects wich are acting as proxy to entities such as:
public class Drawer{
@Autowired
private CardRepository cardRepository;
private DrawerEntity drawerEntity;
public Drawer(){this.drawerEntity = new DrawerEntity();}
public Drawer(DrawerEntity drawerEntity){this.drawerEntity = drawerEntity;}
public int getId(){return drawerEntity.getId();}
public void setId(int id){drawerEntity.setId(id);}
public String getLabel(){return drawerEntity.getLabel();}
public void setLabel(String label){drawerEntity.setLabel(label);}
public int getNumberOfCards(){return cardRepository.countByDrawerId(this.getId());}
}
I've also a service layer :
public interface DrawerService {
Collection<Drawer> findAll();
Drawer findOne(int id);
Drawer create(Drawer drawer);
void delete(int id);
}
Implemented by a DrawerServiceBean
@Service
public class DrawerServiceBean implements DrawerService {
@Autowired
private DrawerRepository drawerRepository;
@Override
public Collection<Drawer> findAll() {
Collection<Drawer> allCard = new ArrayList<>();
for(DrawerEntity drawerEntity : drawerRepository.findAll()){
allCard.add(new Drawer(drawerEntity));
}
return allCard;
}
@Override
public Drawer findOne(int id) {return new Drawer(drawerRepository.findOne(id));}
@Override
public Drawer create(Drawer drawer) {return new Drawer(drawerRepository.save(drawer.getDrawerEntity()));}
@Override
public void delete(int id) {drawerRepository.delete(id);}
}
Which is linked to a JPA repository
@Repository
public interface DrawerRepository extends JpaRepository<DrawerEntity, Integer> {}
Following the advices given in this answer, I'm not injecting anything into the entities and I'm using business proxy objects. But then, it seems that, I have to use @Configurable
and AspectJ LTW for injecting the repositories into the business objects because "Spring AOP only supports method execution join points for Spring beans".
The goal of this architecture was to be able to define methods such as getNumberOfCards
in business objects that use different types of repositories (CardRepository
, DrawerRepository
). But the result seems complex with a lot of boilerplate code. I wonder how I can simplify this? Is Aspect Oriented Programming necessary? Can I reduce the size of the boilerplate code? Is there some solutions provided by Spring Data?
DrawerService
and the POJODrawer
. The problem is how to encapsulate the JPADrawerEntity
to present an enriched business object such asDrawer
.