SQLContainer property types are Object when table is empty

Hi everyone.
I have a SQLContainer with a TableQuery delegate. The problem I am having is that when the SQL table which the TableQuery is set to is empty (has 0 rows) SQLContainer thinks that every column property type is java.lang.Object, instead of String or int, which it gets when there are rows in the table.

This causes commits to fail when a form bound to a new item in the SQLContainer has one or more fields left at a null value, as StatementHelper.handleNullValue doesn’t know what to do.

I have tracked the root of the problem to this piece of code in SQLContainer.getPropertyIds() :


                rs = delegate.getResults(0, 1);
     ...
                /* Try to determine the column's JDBC class by all means. */
                if (resultExists && rs.getObject(i) != null) {
                    type = rs.getObject(i).getClass();
                } else {
                    try {
                        type = Class.forName(rsmd.getColumnClassName(i));
                    } catch (Exception e) {
                        logger.log(Level.WARNING, "Class not found", e);
                        /* On failure revert to Object and hope for the best. */
                        type = Object.class;
                    }
                }

I hope you can see the issue here. Instead of determining the type from the data type of the SQL table columns, it determines the type from objects returned from a ResultSet. But if there are no results, then null will be returned and SQLContainer will fall back to Object type.

What is the best way to deal with this? So far I haven’t found a way to override the property types of SQLContainer.

Thanks!

Hi,

I can see the issue here: when the ResultSet is empty, the metadata is probably empty too. I did not confirm this (I actually thought the metadata would be populated anyway) but if the line 9 in your code snippet is not getting the correct type then the metadata is probably empty.

From a quick look to the code the best fix would be to get the data types from a DatabaseMetaData object. Please create a ticket for this in the Vaadin trac. Unfortunately I don’t see a simple way for you to override the current behavior.

-Tepi