I'm trying to set up a Spring configuration with tutorials and some stuff. It seems everything is OK but when I call the constructor of a Bean with a @Resource everything blows up.
I'm am also giving a try to Apache Click killing two birds with one stone.
Please, can anyone tell me what happens here and how could I fix this?
Thank you.
Caused by: java.lang.RuntimeException: No Context available on ThreadLocal Context Stack
at org.apache.click.Context$ContextStack.peek(Context.java:934)
at org.apache.click.Context$ContextStack.access$000(Context.java:885)
at org.apache.click.Context.getThreadLocalContext(Context.java:168)
at org.apache.click.extras.control.MenuFactory.loadFromMenuXml(MenuFactory.java:495)
at org.apache.click.extras.control.MenuFactory.getRootMenu(MenuFactory.java:302)
at org.apache.click.extras.control.MenuFactory.getRootMenu(MenuFactory.java:255)
at org.apache.click.extras.control.MenuFactory.getRootMenu(MenuFactory.java:197)
at org.test.pages.BasePage.<init>(BasePage.java:15)
at org.test.pages.HomePage.<init>(HomePage.java:24)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:126)
... 30 more
<context:annotation-config />
<context:component-scan base-package="org.test" />
<tx:annotation-driven />
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="oracle.jdbc.OracleDriver" />
<property name="jdbcUrl" value="jdbc:oracle:thin:@192.168.0.10:1521:xe" />
<property name="user" value="HR" />
<property name="password" value="hr"/>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="ctest" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="showSql" value="true" />
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<display-name>CTest</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>ClickServlet</servlet-name>
<servlet-class>org.apache.click.extras.spring.SpringClickServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ClickServlet</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
Edit: I changed the code as suggested but my dao is still null. Also at the appContext I put:
<context:component-scan base-package="org.test.pages" scope-resolver="org.apache.click.extras.spring.PageScopeResolver"/>
Ok, I tried to inject my Dao in my IndexPage but in the constructor cTestDao is null.
What am i doing wrong?
Thanks
@Component @Scope("prototype")
public class IndexPage extends Page {
@Resource
protected CTestDao<Employee> cTestDao;
public IndexPage(){
super();
List<Employee> list = cTestDao.getBeans(Employee.class);
for(Employee e:list){
String s = String.format("Name:%1 Last Name:%2 Salary%3€",e.getFirstName(),e.getLastName(),e.getSalary());
System.out.println(s);
}
}
}
It seems as if you want to treat Click pages like Spring beans, in other words you want Spring to create your Click page and inject the dependencies. Spring supports two types of dependency injection: through setter methods and constructor. In your example above you are accessing the dao in your Page constructor, but the dao can only be injected after the page has been constructed.
I suggest you move your code into the Page onInit() method.
Alternatively you could inject the DAO into the Page constructor "IndexPage(CTestDao dao)", but I haven't tested whether that will work or not.
Kind regards
Bob