0

I have spring based multimodule application. And in my DAO module the DB (embedded derby) is started and created by the class the implements ApplicationListener.

Problem that in the logs the huge stacktrace from Spring which say that there is no db(couldn't get connection).

Still, my application works without any problems. This stacktrace appeared before the ApplicationListener invoked and the db is created. Actually, I see it only when I am starting the application the first time on the machine, because the db created only this time, than it just used.

So my question is whow to avoid this exception in logs? Maybe there is spring or hibenate setup not connect to the db before the application context fully loaded? Or invoke the code that creates db by some other listener?

serg
  • 1,003
  • 3
  • 16
  • 26
  • And ... why don't you load the database from the application context ? – Serge Ballesta Sep 19 '14 at 15:56
  • How? It is not exists before the application context calls refresh... I don't know how to call any java code before the application context created – serg Sep 19 '14 at 16:02

2 Answers2

0

I suppose you are fetching some data from database from inside spring beans that are being created. Perhaps thru @PostConstruct or other way. Remember that until spring context is fully loaded some beans can have injected uninitialized beans.

So do not use DB, do not call any DAOs until you are sure that spring context is fully initialized.

To do such initial calls to DAOs try such patter that guarantees spring context completness:

@Component
public class SpringContextMonitor implements ApplicationListener<ApplicationEvent> {

  @Autowired
  private SomeDao dao;

  ...

  @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ContextRefreshedEvent) {
            onStart((ContextRefreshedEvent) event);
        }
    }

  private void onStart(ContextRefreshedEvent event) {

    // do your initialization here
    dao.getSomething();
    dao2.getSomething();
    ...

  }

  ...
}

The onStart method in above example is place where you are sure that all beans are fully initialized

przemek hertel
  • 3,924
  • 1
  • 19
  • 27
  • Thanks for your help. I think your work around is really good, likely slightly changing the design like Serge Ballesta offered, cause that there is no need in any workarounds – serg Sep 20 '14 at 07:53
0

Well here is the way I do : the ROOT context contains the datasource, the dao, the service and the transaction manager. In XML config, the declaration of the database is :

<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
      p:url="jdbc:derby:/path/to/database;create=TRUE" 
      p:username="user" p:password="pwd"
      p:driverClassName="org.apache.derby.jdbc.EmbeddedDriver"/>

it can then be used to declare a session factory for hibernate and an associated DAO as :

<bean class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
      id="sessionFactory" p:dataSource-ref="datasource">
    <!-- hibernate config -->
    ...
</bean>
<bean class="org.springframework.orm.hibernate4.HibernateTransactionManager"
      name="transactionManager" p:sessionFactory-ref="sessionFactory"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="myDao" class="... .myDaoImpl" p:sessionFactory-ref="sessionFactory" .../>

That way all is created by spring, that ensures that the creation order is correct. Of course the same is possible in Java config with the same logic.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Thank you!!! Your idea to give the Spring capability to create the DB solve my problem. Now there is no exceptions and also it gives me the opportunity to us Spring JdbcTemplates at the time when I am init the DB. – serg Sep 20 '14 at 07:44