0

I have a webapp with maven, eclipselink, jpa, spring 5, jsf2.3, java 8, primefaces 11 deployed on tomcat 8.5.

For a software modernization question I just successfully ported to tomcat 9 with java 17 keeping spring 5 and all the rest of the libs.

But this was just an intermediate step towards porting to tomcat 10.0, java 17 and advancement to jakarta of all dependencies including advancement to spring 6: this port is giving several problems.

I've been stuck on a problem with entity manager configuration for a while now.

The application is configured from a class that extends org.springframework.web.servlet.support.AbstractDispatcherServletInitializer, inside the onStartup method I define the Faces Servlet and other jsf/primefaces stuff. Inside the method getRootConfigClasses I list my various spring config files:

@Override
protected Class<?>[] getRootConfigClasses() {
     return new Class[] { 
             WebMvcConfig.class,
             RepositoryConfig.class,
             SecurityConfiguration.class,
             CachingConfig.class,
             MethodSecurityConfig.class,
             HttpClientConfig.class
             }; 
}

the problem is with RepositoryConfig, this is the class:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories("here.my.package.with.repositories")
public class RepositoryConfig implements TransactionManagementConfigurer {
    
    protected Logger logger = LogManager.getLogger(this.getClass());
    
    @Autowired 
    @Qualifier("config")
    private Config config;  
    
    @Bean(name="entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        
        emf.setDataSource(dataSource());
        
        emf.setPackagesToScan(new String[] { 
                "here.my.package.with.entities"
                });
        
        emf.setJpaVendorAdapter(jpaAdapter());
        
        Properties jpaProperties = new Properties();
        
        JpaDialect jpaDialect = new EclipseLinkJpaDialect();
        emf.setJpaDialect(jpaDialect);
        
        jpaProperties.put("eclipselink.weaving", "false");
        
        
        emf.setJpaProperties(jpaProperties);

        return emf;
    }
    
    
    @Bean(name="jpaAdapter")
    public EclipseLinkJpaVendorAdapter jpaAdapter() {
        EclipseLinkJpaVendorAdapter hjva = new EclipseLinkJpaVendorAdapter();
        hjva.setDatabasePlatform("org.eclipse.persistence.platform.database.MySQLPlatform");
        hjva.setGenerateDdl(false);
        hjva.setShowSql(false);
        return hjva;
    }
    
    @Bean(name="dataSource")
    public DataSource dataSource() {
        JndiTemplate template = new JndiTemplate();
        DataSource ds = null;
        try {
            ds = (DataSource) template.lookup("java:/comp/env/" + config.get("repository.jndi.name"));
        } catch (NamingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return ds;
    }

    
    @Bean(name="transactionManager")
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
        try {
            jpaTransactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
            jpaTransactionManager.setDataSource(dataSource());
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return jpaTransactionManager;
    } 
    
    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return transactionManager();
    }   
    
    @Bean(name="persistenceAnnotation")
    public PersistenceAnnotationBeanPostProcessor persistenceAnnotation() {
        return new PersistenceAnnotationBeanPostProcessor();
    }
}

I get this error:

 Error creating bean with name 'entityManagerFactory' defined in it.baseapp.conf.RepositoryConfig: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception with message: Error creating bean with name 'entityManagerFactory' defined in it.baseapp.conf.RepositoryConfig: Failed to instantiate
..
Error creating bean with name 'entityManagerFactory' defined in it.baseapp.conf.RepositoryConfig: Unexpected exception during bean creation
..
it always repeats this error for several lines
...
12:47:54.521 [main] ERROR it.baseapp.conf.RepositoryConfig$$SpringCGLIB$$0 - @Bean method RepositoryConfig.entityManagerFactory called as bean reference for type [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] but overridden by non-compatible bean instance of type [jdk.proxy3.$Proxy76]. Overriding bean of same name declared in: it.baseapp.conf.RepositoryConfig
[EL Info]: 2023-07-05 12:47:55.433--ServerSession(2050864629)--EclipseLink, version: Eclipse Persistence Services - 4.0.2.v202306161219
[EL Warning]: metamodel: 2023-07-05 12:47:56.449--The collection of metamodel types is empty. Model classes may not have been found during entity search for Java SE and some Java EE container managed persistence units.  Please verify that your entity classes are referenced in persistence.xml using either <class> elements or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element
[EL Warning]: metamodel: 2023-07-05 12:47:57.378--The collection of metamodel [ManagedType] types is empty. Model classes may not have been found during entity search for Java SE and some Java EE container managed persistence units.  Please verify that your entity classes are referenced in persistence.xml using either <class> elements or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element.  The lookup on [class here.my.package.with.entities.OneOfMyEntities] will return null.
[EL Warning]: metamodel: 2023-07-05 12:47:57.618--The collection of metamodel [ManagedType] types is empty. Model classes may not have been found during entity search for Java SE and some Java EE container managed persistence units.  Please verify that your entity classes are referenced in persistence.xml using either <class> elements or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element.  The lookup on [class here.my.package.with.entities.OneOfMyEntities] will return null.
12:47:57.637 [main] ERROR org.springframework.web.context.ContextLoader - Context initialization failed  

I report an extract from the pom.xml regarding the dependencies involved:

<dependency>   
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>eclipselink</artifactId>
    <version>4.0.2</version>
</dependency>

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
    <version>3.1.1</version>
</dependency>

various spring dependency at version 6.0.10
for example:
 <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>6.0.10</version>
</dependency>  

The same class "RepositoryConfig" has no problems in the old versions of the webapp indicated at the beginning of this post. Has anyone run into a similar problem?

iljkr
  • 161
  • 1
  • 1
  • 8
  • The EclipseLink warning "The collection of metamodel types is empty" tells that the Spring package scan isn't giving EclipseLink your entities for processing - but means the persistence unit is attempting to be deployed somehow. The "RepositoryConfig.entityManagerFactory .. overridden by non-compatible bean instance of type [jdk.proxy3.$Proxy76]" might point at the problem, but you may need to put in break points in the RepositoryConfig entityManagerFactory() method and see what the difference is in the before and after migration runs to figure it out. – Chris Jul 05 '23 at 17:55

1 Answers1

0

Little update, in the while I resolve this part of the errors:

"Error creating bean with name 'entityManagerFactory'..@Bean method RepositoryConfig.entityManagerFactory called as bean reference for type [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] but overridden by non-compatible bean instance of type [jdk.proxy3.$Proxy76]. Overriding bean of same name declared in: it.baseapp.conf.RepositoryConfig"

I explicitly added the build dependencies between the beans declared via the @DependsOn annotation:

@Bean(name="entityManagerFactory")
@DependsOn({"dataSource","jpaAdapter"})
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
...
@Bean(name="transactionManager")
@DependsOn({"entityManagerFactory","dataSource"})
public PlatformTransactionManager transactionManager() {

Strange, the same config class in the previsous version of the same web app worked without DependsOn.

This error remains:

[EL Warning]: metamodel: 2023-07-07 13:44:35.492--The collection of metamodel types is empty. Model classes may not have been found during entity search for Java SE and some Java EE container managed persistence units.  Please verify that your entity classes are referenced in persistence.xml using either <class> elements or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element

I'll update this answer as soon as I fix this part as well.

iljkr
  • 161
  • 1
  • 1
  • 8
  • Another update: I solved also the part "The collection of metamodel types is empty". The RepositoryConfig in this post is ok, i did a thorough review of all the libraries in the project and there were some i didn't notice they were still using javax, after painstakingly updating all the dependencies version now it works. – iljkr Jul 26 '23 at 07:04
  • And in addition to checking that all dependencies (even those apparently not jpa related) are using jakarta i checked the consistency of the servlet api libraries versions against whether to use a 10.0.x or 10.1.x tomcat as indicated here by BalusC: https://stackoverflow.com/a/65704617/3147345 – iljkr Jul 26 '23 at 07:06