Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird spring "unresolvable circular reference issue"

In my application we are using multiple data-sources hence we have multiple database configurations(session factories). Everything works perfectly fine on our local(whindows machine) but when we deploy war file to Unix application failed with following exception:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cpnRepository': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory org.npcc.ccms.dao.GenericDB1Dao.sessionFactory; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'DB1Config': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory org.npcc.ccms.config.db.DB1Config.sessionFactory; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'DB1SessionFactory': Requested bean is currently in creation: Is there an unresolvable circular reference?

Here is the dao implementation:

@Repository("cpnRepository")
public class ProgramNodeDaoImpl extends GenericDB1Dao<Integer, CustomProgramNode> implements CPNRepositoryDao {
    @Override
    public List<CustomProgramNode> findAllNodes() {
        Criteria criteria = createEntityCriteria();
        return (List<CustomProgramNode>) criteria.list();
    }

    @Override
    public List<CustomProgramNode> findByStatus(String status) {
        Query query = getSession().createQuery("from CustomProgramNode where status = :status");
        query.setParameter("status", status);
        List<CustomProgramNode> list = query.list();
        return list;        

    }

}

Generic DAO of DB1:

public abstract class GenericDB1Dao<PK extends Serializable, T> {

    private final Class<T> persistentClass;

    @SuppressWarnings("unchecked")
    public GenericAgrgtrDao(){
        this.persistentClass =(Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
    }

    @Autowired
    @Qualifier("DB1SessionFactory")
    private SessionFactory sessionFactory;

    protected Session getSession(){
        return sessionFactory.getCurrentSession();
    }

    @SuppressWarnings("unchecked")
    public T getByKey(PK key) {
        return (T) getSession().get(persistentClass, key);
    }

    public void persist(T entity) {
        getSession().persist(entity);
    }

    public void delete(T entity) {
        getSession().delete(entity);
    }

    protected Criteria createEntityCriteria(){
        return getSession().createCriteria(persistentClass);
    }
}

Database1 Configuration:

@Configuration
public class DB1Config {
    final static Logger logger = LogManager.getLogger(DB1Config.class);

    @Autowired
    private Environment environment;

    @Autowired
    @Qualifier("DB1SessionFactory")
    private SessionFactory sessionFactory;

    @Bean(name="DB1SessionFactory")
    public LocalSessionFactoryBean db1SessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan(new String[] { "org.npcc.ccms.model.db1" });
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
     }

    @Bean(destroyMethod="")
    public DataSource dataSource() {
        JndiTemplate jndi = new JndiTemplate();
        DataSource dataSource = null;
        try {
            dataSource = (DataSource) jndi.lookup(environment.getRequiredProperty("datasource.db1"));
        } catch (NamingException e) {
        }
        return dataSource;
    }

    private Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
        properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
        properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
        return properties;        
    }
    @Primary
    @Bean(name="DB1TransactionManager")
    public HibernateTransactionManager db1TransactionManager() {
       HibernateTransactionManager txManager = new HibernateTransactionManager();
       txManager.setSessionFactory(this.sessionFactory);
       txManager.setDataSource(dataSource());
       return txManager;
    }
}

How does Spring resolve bean dependencies? Why isn't the order consistent between two OS-es? Thanks in Advance.

like image 458
Ramu Avatar asked Oct 31 '22 17:10

Ramu


1 Answers

I think your problem comes from the fact that you are creating a LocalSessionFactoryBean and at the same time trying to autowire SessionFactory ...

You don't need that class member sessionFactory in your DB1Config class, try something like that :

@Bean(name="DB1SessionFactory")
public LocalSessionFactoryBean db1SessionFactory() {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan(new String[] { "org.npcc.ccms.model.db1" });
    sessionFactory.setHibernateProperties(hibernateProperties());
    return sessionFactory;
 }

@Bean
public SessionFactory sessionFactory() {
    return db1SessionFactory().getObject();
}
like image 140
Pras Avatar answered Nov 08 '22 12:11

Pras