Handle Entity annotations for multiple databases (SQL and NoSQL) when only one is active at a time?

51 Views Asked by At

I have a school project that needs to support different db at runtime, when only one is selected and is active (a feature to change db after one is selected is not needed).

I've been doing some reading and the following link helped a bit, but I have some questions. https://docs.spring.io/spring-data/jpa/docs/current/reference/html/

The thing is everything I find always runs 2 db at the same time so they apply the anotations on diferent classes.

I need something to work with the following:

@Entity
class User { … }


@Document
class User { … }

The scenario:

I don't know if it's possible, but I was thinking the service.class and the repository.class to refer to a User.class instead of UserH2.class or UserMongo.class, using a UserFactory.class to create the user accorrdingly to the active db.

How could I make the User.class with all the attributes and base methods so it would then be used by UserH2.class or UserMongo.class to set the respective annotations?

If i'm not mistaken, the repositories could be something like:

@NoBeanRepository
class UserRepository { … }

@Repository
@ConditionalOnProperty(name = "myapp.db.active", havingValue = "h2")
class UserRepositoryH2 extends UserRepository, CrudRepository<User, Long> { … }

@Repository
@ConditionalOnProperty(name = "myapp.db.active", havingValue = "mongo")
class UserRepositoryMongo extends UserRepository, MongoRepository<User, Long> { … }

Thank you!

1

There are 1 best solutions below

0
Atram On BEST ANSWER

Solved by respecting Clean Architecture rules:

Domain classes should not have any dabatase related info.

Therefore, JPA/Mongo classes were added with the annotations required by each database type.

  • UserJPA
  • UserMongo

Also it was created UserJpaAssembler and UserMongoAssembler for each class to handle the mapping.

Each repository class will then inject the requires classes, for example:

  • UserRepositoryJpaImplwill inject UserJPA and UserJpaAssembler
  • UserRepositoryMongoImplwill inject UserMongo and UserMongoAssembler

To define the active repository implementation we can use @Profiles, @ConditionalOnProperty, ... and define a variable in the application.properties that will control each database is active.