2

I am using JPA, H2, EclipseLink, Java Config (no xml). My problem is that I am getting this No [ManagedType] was found for the key class error below. It suggests adding <exclude-unlisted-classes>false</exclude-unlisted-classes> to my persistence.xml, but I am not using xml for configuration, so I am not sure how to fix it.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.foo.data.repository.RepositoryTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.foo.data.repository.UserRepository com.foo.data.repository.RepositoryTest.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: No [ManagedType] was found for the key class [com.foo.data.model.User] in the Metamodel - please verify that the [Managed] class was referenced in persistence.xml using a specific <class>com.foo.data.model.User</class> property or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element.
   at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1146)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:376)
   at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110)
   at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
   at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:312)
   at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
   at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
   at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
   at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284)
   at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
   at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
   at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
   at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
   at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
   at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
   at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
   at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
   at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
   at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
   at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
   at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Here is an excerpt from my @Configuration class.

@ComponentScan(
      basePackages = { "com.foo.*"},
      excludeFilters = @Filter(type = FilterType.ANNOTATION,
      value = Configuration.class))
@Configuration
@EnableJpaRepositories(basePackages = "com.foo.data.repository")
public class SeleniumAppTestConfig implements InitializingBean {

   @Bean
   public DataSource dataSource() {
      EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
      return builder.setType(EmbeddedDatabaseType.H2)
            .addScript("SeleniumCreateScript.sql").build();
   }

   @Bean
   public Properties jpaProperties() {
       Properties props = new Properties();
       props.setProperty("eclipselink.ddl-generation", "create-tables");
       props.setProperty("eclipselink.weaving", "false");
       props.setProperty("eclipselink.logging.level", "FINEST");
       props.setProperty("eclipselink.logging.parameters", "true");
       return props;
   }

   @Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
      final PersistenceProvider persistenceProvider = new PersistenceProvider();

      final EclipseLinkJpaVendorAdapter vendorAdapter =
            new EclipseLinkJpaVendorAdapter();
      vendorAdapter.setGenerateDdl(true);
      vendorAdapter.setShowSql(true);
      vendorAdapter.setDatabase(Database.H2);

      LocalContainerEntityManagerFactoryBean emf =
            new LocalContainerEntityManagerFactoryBean();
      emf.setDataSource(dataSource());
      emf.setPackagesToScan("com.foo.data.model");
      emf.setLoadTimeWeaver(new SimpleLoadTimeWeaver());
      emf.setPersistenceProvider(persistenceProvider);
      emf.setPersistenceUnitName("SeleniumTests");
      emf.setJpaVendorAdapter(vendorAdapter);
      emf.setJpaProperties(jpaProperties());
      emf.afterPropertiesSet();
      return emf;
   }

   @Bean
   public PlatformTransactionManager transactionManager(){
      JpaTransactionManager transactionManager = new JpaTransactionManager();
      transactionManager.setEntityManagerFactory(
            entityManagerFactory().getObject() );

      return transactionManager;
   }

   @Bean
   public EclipseLinkJpaDialect exceptionTranslator() {
      return new EclipseLinkJpaDialect();
   }

}

Here is my Entity class (in the com.foo.data.model package):

@Entity
@Table(name = "USER", schema = "SELENIUM")
public class User {
   @Id
   @Column (name = "USERNAME")
   private String username;
   @Column (name = "PASSWORD")
   private String password;

   public String getUsername() {
      return username;
   }
   public void setUsername(String username) {
      this.username = username;
   }
   public String getPassword() {
      return password;
   }
   public void setPassword(String password) {
      this.password = password;
   }

   @Override
   public String toString() {
      return String.format(
            "User[username=%s, password='%s']",
            username, password);
   }

}

Here is my Repository:

@Repository
public interface UserRepository extends CrudRepository <User, String> {
   List<User> findByLastUsername(String username);
}

And finally, here is my Test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SeleniumAppTestConfig.class)
public class RepositoryTest {

   /** Logger for this class. */
   private static final Logger LOG =
         Logger.getLogger(RepositoryTest.class);

   @Autowired
   private UserRepository userRepository;

   @Test
   public void testThings() {
      final Iterable<User> users = userRepository.findAll();
      for (User user: users) {
         LOG.info("user [" + user + "].");
      }
   }
}
Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
Robert Mark Bram
  • 8,104
  • 8
  • 52
  • 73

5 Answers5

4

Specify the entities base package using @EntityScan on your SeleniumAppTestConfig.

aux
  • 1,589
  • 12
  • 20
3

Just give a dummy name to each of the individual PersistenceUnitName. No persistence.xml needed

factory.setPersistenceUnitName("dummy1"); factory.setPersistenceUnitName("dummy2");

  • This did the trick finally. After getting it to work with hibernate I tried this with eclipselink and if worked. so im sticking with EL for now. – Jacques Koorts Apr 02 '20 at 09:52
2

The problem here is a mix of configuration via persistence.xml and component scanning. The setup defines a persistence unit name (in the setup of the LocalContainerEntityManagerFactoryBean) which makes Spring use that and drop the packages to scan as it can't augment an existing persistence unit.

This would've been revealed by activating debug logging as DefaultPersistenceUnitManager.readPersistenceUnitInfos(…) logs a message in exactly that case.

I've filed a ticket to improve the logging in that erroneous configuration state to make the problem more obvious.

Oliver Drotbohm
  • 80,157
  • 18
  • 225
  • 211
2

Update to eclipse link 2.7.8-RC1

ajaygoyal
  • 31
  • 3
-7

Solved my problem by moving to Hibernate instead of EclipseLink.

Robert Mark Bram
  • 8,104
  • 8
  • 52
  • 73
  • This was my solution too. I had multiple datasource and used autoconfiguration. The sad thing is the error refered to persistence.xml but I did not even had such a file. – Jacques Koorts Apr 02 '20 at 09:41