Unable to use ComboBox+SQLContainer (beta9 & 10)

I’m trying to show a page with a ComboBox using SQLContainer. All I’m getting is this exception:

Nov 30, 2012 8:51:43 AM com.vaadin.server.DefaultErrorHandler doDefault
SEVERE: 
java.lang.IllegalStateException: A connector should not be marked as dirty while a response is being written.
	at com.vaadin.ui.ConnectorTracker.markDirty(ConnectorTracker.java:295)
	at com.vaadin.server.AbstractClientConnector.markAsDirty(AbstractClientConnector.java:139)
	at com.vaadin.ui.AbstractSelect.fireItemSetChange(AbstractSelect.java:1641)
	at com.vaadin.ui.AbstractSelect.containerItemSetChange(AbstractSelect.java:1608)
	at com.vaadin.ui.ComboBox.containerItemSetChange(ComboBox.java:439)
	at com.vaadin.data.util.sqlcontainer.SQLContainer.fireContentsChange(SQLContainer.java:1564)
	at com.vaadin.data.util.sqlcontainer.SQLContainer.refresh(SQLContainer.java:856)
	at com.vaadin.data.util.sqlcontainer.SQLContainer.updateCount(SQLContainer.java:1105)
	at com.vaadin.data.util.sqlcontainer.SQLContainer.getItemIds(SQLContainer.java:326)
	at com.vaadin.ui.AbstractSelect.getItemIds(AbstractSelect.java:727)
	at com.vaadin.ui.ComboBox.getFilteredOptions(ComboBox.java:583)
	at com.vaadin.ui.ComboBox.paintContent(ComboBox.java:215)
	at com.vaadin.server.LegacyPaint.paint(LegacyPaint.java:65)
	at com.vaadin.server.AbstractCommunicationManager.legacyPaint(AbstractCommunicationManager.java:1342)
	at com.vaadin.server.AbstractCommunicationManager.writeUidlResponse(AbstractCommunicationManager.java:833)
	at com.vaadin.server.AbstractCommunicationManager.getInitialUIDL(AbstractCommunicationManager.java:2547)
	at com.vaadin.server.AbstractCommunicationManager.handleBrowserDetailsRequest(AbstractCommunicationManager.java:2387)
	at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:325)
	at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:201)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:304)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
	at java.lang.Thread.run(Thread.java:722)

I initialize the application with the following lines:

protected void init(VaadinRequest request) {
	VaadinSession session = VaadinSession.getCurrent();
	session.setConverterFactory(new MyConverterFactory());
	session.setLocale(new Locale("fi", "FI"));
	session.setAttribute(DB.class, new DB()); // Creating a new instance of DB will initialize the SQLContainers

	SingleComponentContainer container = new Panel();
	container.setWidth(100, Unit.PERCENTAGE);
	setContent(container);

	Navigator nav = new Navigator(this, container);
	setNavigator(nav);
	for(Views view : Views.values()) {
	    nav.addView(view.toString(), view.getViewClass());
	}

	nav.navigateTo(Views.MAIN.toString());
}

This calls my main view’s enter() method that calls a private init() method which will initialize the components, including the ComboBox with a SQLContainer. There’s nothing special with the creation of ComboBox; I give it a caption and call setContainerDataSource() method. I’ve checked that SQLContainer gets the property id’s and row count.

It seems such a simple case. Does anybody have a clue why this isn’t working?

A few other remarks:

  • View.enter is called twice after I call nav.navigateTo(). On the first call, ViewChangeEvent.getOldView() returns null and on the second call it returns MainPage.
  • Filters in SQLContainers querydelegate are ignored. Is this intentional? If yes, then what is the purpose of QueryDelegate.setFilters?

I tried the same SQLContainer with a Table and it works just fine. There must be something peculiar with ComboBox…

I created a simple example to see if the problem was in my (more complex) application. Turns out the problem is not in my application, so I filed a bug and attached the demo application:
http://dev.vaadin.com/ticket/10458

I run into the same issue with a TwinColSelect component. I’m not using any threads in my sample app. And when changing the TwinColSelect to a normal combobox everything is fine.

As I can’t register to log a defect (my email address is rejected as invalid), can you please accept this as a defect report.

Thanks