3

I have a Spring application that connects to two databases at the same time. So I have for this two LocalSessionFactoryBean instances for each connection like this:

@Bean
public LocalSessionFactoryBean firstSessionFactory() {
    final LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();
    lsfb.setPackagesToScan("ro.mycompany.myproject.classes");
    lsfb.setDataSource(dataSourceOne);
    lsfb.setEntityInterceptor(auditInterceptor1);
    lsfb.setHibernateProperties(getHibernateProperties1());
    return lsfb;
}

@Bean
public LocalSessionFactoryBean secondSessionFactory() {
    final LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();
    lsfb.setPackagesToScan("ro.mycompany.myproject.classes2");
    lsfb.setDataSource(dataSourceTwo);
    lsfb.setEntityInterceptor(auditInterceptor2);
    lsfb.setHibernateProperties(getHibernateProperties2());
    return lsfb;
}

For the DAO layer I have a class that injects the SessionFactory object like this.

public class GenericDAOImpl extends HibernateDAOSupport implements GenericDAO {
     @Autowired 
     private SessionFactory sessionFactory;
     //Other methods goes here
}

I instantiate the beans in my config file like this:

@Bean
public GenericDAO firstGenericDAO() {
    final GenericDAOImpl genericDAO = new GenericDAOImpl();
    return genericDAO;
}

@Bean
public GenericDAO secondGenericDAO() {
    final GenericDAOImpl genericDAO = new GenericDAOImpl();
    return genericDAO;
}

How can I make the firstGenericDAO to use firstSessionFactory and secondGenericDAO to use secondSessionFactory without creating the setters method? I want to use both connection at the same time so also Spring profiles won't help me. Thank you

Daniel Jipa
  • 878
  • 11
  • 24

2 Answers2

1

Either use @Qualifier("...") in addition to @Autowired or just use @Resource(name = "..."). Personally I prefer using @Resource as it replaces the two Annotations with the single one.

In your case, @Resource(name = "firstSessionFactory") and @Resource(name = "secondSessionFactory") respectively.

user2004685
  • 9,548
  • 5
  • 37
  • 54
  • Maybe I wasn't that clear with my question. If I use the `Qualifier` annotation on my `GenericDAOImpl` I will tie that class only with a sessionFactory. I want to use the same class for both session factories. – Daniel Jipa Jan 25 '16 at 11:30
  • In that case create a setter for `SessionFactory` and pass the reference of the required `SessionFactory` bean to the setter while you are creating the bean of your DAO. – user2004685 Jan 25 '16 at 11:33
  • I was afraid that was the only solution. I do not have easy access to that class. Thank you. So I think annotations with Spring are a bit less powerfull than xml configuration. – Daniel Jipa Jan 25 '16 at 11:38
  • Well I personally prefer XML over class configuration. If you are happy then please accept the answer and help close the question. – user2004685 Jan 25 '16 at 11:44
1

For you following code,

public class GenericDAOImpl extends HibernateDAOSupport implements GenericDAO {
     @Autowired 
     private SessionFactory sessionFactory;
     //Other methods goes here
}

Spring should be known clearly which bean would be autowired. That means, there should be setter method or some other variable to distinguish your sessionFactory1 and sessionFactory2.

Just as you said, xml-based is still power than annotation. If you don't want to use XML based, and don't want setter method either, I think sessionFactory can be initialized by another variable to identify which bean used.

For example,

public class GenericDAOImpl extends HibernateDAOSupport implements GenericDAO {
    private SessionFactory sessionFactory;

    public GenericDAOImpl(boolean tag) {
        super();
        ApplicationContext apx = new AnnotationConfigApplicationContext(xxxx.class);
        sessionFactory = tag ? (SessionFactory) apx.getBean("sessionFactory1")
                : (SessionFactory) apx.getBean("sessionFactory1");
    }
}

Of course, you need to specify the bean name for LocalSessionFactoryBean with @Bean(name = "sessionFactory1") and @Bean(name = "sessionFactory2")

Junjie
  • 1,145
  • 3
  • 21
  • 37
  • I will try to use the solution found here: http://stackoverflow.com/questions/7720454/dynamically-defining-which-bean-to-autowire-in-spring-using-qualifiers – Daniel Jipa Jan 25 '16 at 12:31