Search code examples
javahibernatejpaspring-data-jpaeclipselink

How to spread Entities over different modules in Spring-data-jpa and eclipselink?


I am currently developing an application with a core module and different "extension" modules. The core module includes the JPA configuration based on a Spring configuration class as well as some "basic" entities and their repositories which shall be used in the "extension" modules. The extension modules contain additional Entity classes and JPARepositories. When starting the JUnit Test for an extension module I encounter the following error:

No [ManagedType] was found for the key class [a.b.c.data.Config] in 
the Metamodel - please verify that the [Managed] class was referenced
in persistence.xml using a specific <class>a.b.c.data.Config</class>
property or a global <exclude-unlisted-classes>false</exclude-unlisted-classes>
element.

To accomplish this I tried three different approaches:

  • Created one LocalContainerEntityManagerFactoryBean with the name coreEntityManager with setPackagesToScan including the core and the extension package which contain the @Entity classes and the @EnableJpaRepositories pointing to the core repository package and the spring config of the extension having the @EnableJpaRepositories pointing to the extension repository package
  • Created an additional LocalContainerEntityManagerFactoryBean in the spring config for the extension with its own JPaRepository Annotation and with setPackagesToScan pointing only to the extension package containing the @Entity classes. The coreEntityManager in this case points only to the package in the core module containing the @Entity classes.
  • Created one LocalContainerEntityManagerFactoryBean with the name coreEntityManager with setPackagesToScan including the core and the extension package which contain the @Entity classes and the @EnableJpaRepositories pointing to the core and the extension repo packages

With the first two approaches the already mentioned error shows up while with the third approach there's the config repository not found:

No qualifying bean of type 'a.b.c.ext.repositories.ConfigRepository' available

Code for approach 1:

@Configuration
@ComponentScan(basePackages = {"a.b.c.core.services"})
@EnableJpaRepositories(basePackages = {"a.b.c.core.repositories"}, entityManagerFactoryRef = "coreEntityManager")
public class CoreJPAConfig {
...
    @Bean
    public LocalContainerEntityManagerFactoryBean coreEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        JpaVendorAdapter jpaVendorAdapter = new EclipseLinkJpaVendorAdapter();
        JpaDialect jpaDialect = new EclipseLinkJpaDialect();
        em.setJpaVendorAdapter(jpaVendorAdapter);
        em.setJpaDialect(jpaDialect);
        em.setJpaPropertyMap(getJpaProperties());
        em.setPersistenceUnitName("a.core");
        em.setPackagesToScan("a.b.c.core.data",
                "a.b.c.ext.data");
        em.setDataSource(dataSource());
        return em;
    }
...
}

Configuration
@ComponentScan(basePackages = {
        "a.b.c.config.services"})
@EnableJpaRepositories(basePackages = {"a.b.c.ext.repositories"}, entityManagerFactoryRef = "coreEntityManager")
public class JobSpringConfig {
...
}

code for approach 2:

@Configuration
@ComponentScan(basePackages = {"a.b.c.core.services"})
@EnableJpaRepositories(basePackages = {"a.b.c.core.repositories"}, entityManagerFactoryRef = "coreEntityManager")
public class CoreJPAConfig {
...
    @Bean
    public LocalContainerEntityManagerFactoryBean coreEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        JpaVendorAdapter jpaVendorAdapter = new EclipseLinkJpaVendorAdapter();
        JpaDialect jpaDialect = new EclipseLinkJpaDialect();
        em.setJpaVendorAdapter(jpaVendorAdapter);
        em.setJpaDialect(jpaDialect);
        em.setJpaPropertyMap(getJpaProperties());
        em.setPersistenceUnitName("a.core");
        em.setPackagesToScan("a.b.c.core.data");
        em.setDataSource(dataSource());
        return em;
    }
...
}

@Configuration
@ComponentScan(basePackages = {"a.b.c.config.services"})
@EnableJpaRepositories(basePackages = {"a.b.c.ext.repositories"}, entityManagerFactoryRef = "jobEntityManager")
public class JobSpringConfig {
...
    @Bean
    public LocalContainerEntityManagerFactoryBean jobEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        JpaVendorAdapter jpaVendorAdapter = new EclipseLinkJpaVendorAdapter();
        JpaDialect jpaDialect = new EclipseLinkJpaDialect();
        em.setJpaVendorAdapter(jpaVendorAdapter);
        em.setJpaDialect(jpaDialect);
        em.setJpaPropertyMap(getJpaProperties());
        em.setPersistenceUnitName("a.config");
        em.setPackagesToScan("a.b.c.ext.data");
        em.setDataSource(dataSource);
        return em;
    }

code for approach 3:

@Configuration
@ComponentScan(basePackages = {"a.b.c.core.services"})
@EnableJpaRepositories(basePackages = {"a.b.c.core.repositories",
        "a.b.c.ext.repositories"}, entityManagerFactoryRef = "coreEntityManager")
public class CoreJPAConfig {
...
    @Bean
    public LocalContainerEntityManagerFactoryBean coreEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        JpaVendorAdapter jpaVendorAdapter = new EclipseLinkJpaVendorAdapter();
        JpaDialect jpaDialect = new EclipseLinkJpaDialect();
        em.setJpaVendorAdapter(jpaVendorAdapter);
        em.setJpaDialect(jpaDialect);
        em.setJpaPropertyMap(getJpaProperties());
        em.setPersistenceUnitName("a.core");
        em.setPackagesToScan("a.b.c.core.data",
                "a.b.c.ext.data");
        em.setDataSource(dataSource());
        return em;
    }
...

What I want to achieve at the end is to have a kind of "Lego" building blocks where the modules and their configuration can simply be added as a dependency and the corresponding configuration entities (and their tables) are added to the persistency unit without the need of further tweaking.

Anyone able to help me?

kind regards

defect


Solution

  • So apparently I wasn't able to see the wood for the trees... I missed the @Entity annotation in one of the extension entities... DUH! facepalm

    Thanks to everyone reading my question and trying to help! Shame on me!