Seam: @In attribute requires non-null value
errorken Feb 17, 2008 11:39 AMI have a JSF page containing a datatable showing a list of customers retrieved from the database. The datatable is linked with a backing bean which retrieves the customers from database using a hibernate session.
The last column of each row in the table has a button. When pressed it will call a method on the backing bean to retrieve the details of that customer.
I made this entirely based on the hibernate
example supplied with seam.
I got it working so that the customers are retrieved by the backing bean from the injected hibernate session. The problem is that when I press the button, an ajax call is made to the backing bean, but here it goes wrong. I get an exception:
Caused by: org.jboss.seam.RequiredException: @In attribute requires non-null value: userTableDataModel.bookingDatabase at org.jboss.seam.Component.getValueToInject(Component.java:2168) at org.jboss.seam.Component.injectAttributes(Component.java:1598) at org.jboss.seam.Component.inject(Component.java:1416) at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:45) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:42) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) at org.jboss.seam.core.SynchronizationInterceptor.aroundInvoke(SynchronizationInterceptor.java:32) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107) at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:166) at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:102) at be.application.UserTableBean_$$_javassist_1.setDataTable(UserTableBean_$$_javassist_1.java) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at javax.el.BeanELResolver.setValue(BeanELResolver.java:108) ... 52 more
Fact is that it wasn't null when the datatable was loaded the first time. Apparantly it gets null
when a second method on the backing bean is invoked.
I tried about everything, but I cannot figure out why I'm getting this.
Any help would be greatly appreciated.
I'm using:
Seam 2.0.1
JBoss 4.2
Trinidad, Richfaces, Tomahawk
My code:
Name("userTableDataModel") @Scope(ScopeType.SESSION) public class UserTableBean implements Serializable { @In Session bookingDatabase; public List getListAll() { customerList = bookingDatabase.createQuery("select c from CustomerTO as c").list(); return customerList; } public void showDetails() { System.out.println("Showing detail"); } }
As you see the show detail is not doing anything besides printing something in the log -- untill now it doesn't get invoked since I'm getting the error prior the method could be invoked.
My faces config:
<faces-config> <managed-bean> <managed-bean-name>userTableDataModel</managed-bean-name> <managed-bean-class> be.application.UserTableBean </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> </faces-config>
The relevant parts of web.xml
<filter> <filter-name>Seam Filter</filter-name> <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class> </filter> <filter> <filter-name>Seam Exception Filter</filter-name> <filter-class> org.jboss.seam.servlet.SeamExceptionFilter </filter-class> </filter> <filter-mapping> <filter-name>Seam Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>Seam Exception Filter</filter-name> <url-pattern>*.jsf</url-pattern> </filter-mapping> <listener> <listener-class>org.jboss.seam.servlet.SeamListener</listener-class> </listener> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping>
Components.xml
<core:manager conversation-timeout="120000" concurrent-request-timeout="500" conversation-id-parameter="cid" /> <persistence:hibernate-session-factory name="hibernateSessionFactory" /> <persistence:managed-hibernate-session name="bookingDatabase" session-factory="#{hibernateSessionFactory}" auto-create="true" /> <transaction:hibernate-transaction session="#{bookingDatabase}" />
Hibernate config:
<hibernate-configuration> <session-factory name="java:/bookingDatabase"> <property name="show_sql">true</property> <property name="connection.datasource">java:jdbc/db</property> <property name="cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property> <property name="transaction.flush_before_completion">true</property> <property name="transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property> <property name="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property> <mapping resource="be/backend/Customer.hbm.xml"/> <mapping resource="be/backend/Product.hbm.xml"/> </session-factory> </hibernate-configuration>
The command button to get the details:
<a4j:commandButton id="show_detail" action="#{userTableDataModel.showDetail}" value="#{msg['userinformation.showdetail']}"