1
votes

I am getting the following error Error creating bean with name 'genericRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Not an managed type: class java.lang.Object

I am new to generics, if there are any generics issue please let me know as well

my Contact.java is in com.merc.template.managelistofobjects.domain package All other classes are in com.merc.template.managelistofobjects package

ContactCollectionManagerImpl

@Component
public class ContactCollectionManagerImpl extends CollectionManagerImpl<Contact> implements CollectionManager<Contact>{

@Autowired
private GenericRepository<Contact,Long> genericRepository;

public ContactCollectionManagerImpl() {
    setGenericRepository(genericRepository);
}

@Override
public void addToCollection(Contact contact, boolean reload){
    super.addToCollection(contact, entityDataMap, reload);
}
}

CollectionManagerImpl

public abstract class CollectionManagerImpl<T extends EntityBean> implements CollectionManager<T>{

private GenericRepository objectManager;

public void setGenericRepository(GenericRepository genericRepository) {
    this.objectManager = genericRepository;
}

protected void addToCollection(T entity, Map<Long,T> entityDataMap, boolean reload) {
    //reload is set to false when the static map needs not be updated
    if(reload){
        //loads all the existing collection objects from db
        loadCollection(entityDataMap, false);

        //check if the obect to be inserted already exists in collection
        if(entityDataMap.containsKey(entity.getId())){
            return;
        }
    }

    //TODO save to database
    objectManager.save(entity);

    if(reload){
        syncCollectionWithDB(entityDataMap);
    }
}
}

CollectionManager

public interface CollectionManager<T> {

public void addToCollection(T object, boolean reload);
}

GenericRepository

public interface GenericRepository<T, ID extends Long> extends JpaRepository<T, ID>{

}

MyApplicationContext

@Configuration
@EnableJpaRepositories
@ComponentScan("com.merc.template.managelistofobjects")
@ImportResource("classpath:spring/app-context.xml")
@PropertySource("classpath:application.properties")
public class MyApplicationContext {

private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";

private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
private static final String PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY = "hibernate.ejb.naming_strategy";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";

@Resource
private Environment environment;

@Bean
public DataSource dataSource() {
    BoneCPDataSource dataSource = new BoneCPDataSource();

    dataSource.setDriverClass(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
    dataSource.setJdbcUrl(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
    dataSource.setUsername(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
    dataSource.setPassword(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));

    return dataSource;
}

@Bean
public JpaTransactionManager transactionManager() throws ClassNotFoundException {
    JpaTransactionManager transactionManager = new JpaTransactionManager();

    transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());

    return transactionManager;
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() throws ClassNotFoundException {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();

    entityManagerFactoryBean.setDataSource(dataSource());
    //setPackagesToScan = com.merc.template.managelistofobjects.domain 
entityManagerFactoryBean.setPackagesToScan(environment.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
    entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistence.class);

    Properties jpaProterties = new Properties();
    jpaProterties.put(PROPERTY_NAME_HIBERNATE_DIALECT, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
    jpaProterties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
    jpaProterties.put(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY));
    jpaProterties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));

    entityManagerFactoryBean.setJpaProperties(jpaProterties);

    return entityManagerFactoryBean;
}

@Bean
public CollectionManager contactCollectionManager(){
    return new ContactCollectionManagerImpl();
}

}

My main class contains the following code

ApplicationContext context = new AnnotationConfigApplicationContext(MyApplicationContext.class);
    CollectionManager collMgr = context.getBean("contactCollectionManager",CollectionManager.class);
    Contact contact = new Contact(2L,"xyz","abc");
    collMgr.addToCollection(contact, true);

entitymanager.packages.to.scan=com.merc.template.managelistofobjects.domain

my spring xml file contains just one line

<jpa:repositories base-package="com.merc.template.managelistofobjects"/>

When i run the code I get the following error java.lang.IllegalArgumentException: Not an managed type: class java.lang.Object

1

1 Answers

1
votes

You cannot autowire an object that takes an generic type, You will have to define a strongly typed sub interface of GenericRepository and then autowire it inside your clases

public interface ContactGenericRepository extends GenericRepository<Contact,Long> {}

Then autowire the new interface

@Autowired
private ContactGenericRepository contractGenericRepository;

P.S: you cannot use the autowired object inside the constructor of the class that wrap it, as you are doing inside the ContactCollectionManagerImpl constructor, as the object is not instantiated yet

You could easily use @PostConstruct on any other method that does that behaviour you want, like this

@PostConstruct
public void populateContactCollectionManagerImpl() {
   setGenericRepository(genericRepository);
}