spring-data-jpaspring-mongodb

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


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!


Solution

  • 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.

    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:

    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.