I have created a SpringBoot based library that creates some records in a relational data base. For the DB access, I use JPA. The lib has a JPA repository and some JPA entities, both placed in their respective java package.
I want that the application that uses my library can easily define what DB the library should work with (the application will access two or three DBs). My solution for that is that the application should define a bean of type EntityManagerFactory
and a bean of type PlatformTransactionManager
, both with 'well known names' (defined in the library).
In the library I have the following config code:
@Configuration
@ConditionalOnBean(value = EntityManagerFactory.class, name = "myLibEntityManagerFactory")
@EnableJpaRepositories(
// Java packages with JPA repositories
basePackageClasses = MyLibRepository.class,
// EntityManager and TransactionManager to use for the DB access
entityManagerFactoryRef = "myLibEntityManagerFactory",
transactionManagerRef = "myLibEntityTransactionManager"
)
// Java packages to scan for entities. The lib knows which entities it needs and scans for them.
// The application should not care about that.
@EntityScan(basePackageClasses = MyLibEntity.class)
@Slf4j
public class MyLibDbAccessConfig {
// Nothing needed here; the class is just a bearer of the 'EnableJpaRepositories' annotation.
}
The idea is that the library also scans for the entities it needs, because they are an implementation detail and the application should not care about them.
In my application, I have a @Configuration class with the following bean:
@Bean
public LocalContainerEntityManagerFactoryBean myLibEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(myLibDataSource()); // Defined in this Configuration class but omitted for brevity
em.setPackagesToScan("my.lib.package"); // <-- I would like to get rid of this line
return em;
}
@Bean
public PlatformTransactionManager myLibEntityTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(myLibEntityManagerFactory().getObject());
return transactionManager;
}
My question is about the EntityScan
annotation and the line commented with "I would like to get rid of this line".
The EntityScan
annotation in the library does not seem to be enough. I also have to call setPackagesToScan
in the application, otherwise the entities are not found and I get this exception:
java.lang.IllegalStateException: No persistence units parsed from {classpath*:META-INF/persistence.xml}
How can I avoid specifying the entities to scan in the application? This information should be set by the library.