--- title: Editing order: 4 layout: page --- [[sqlcontainer.editing]] = Editing Editing the items ( [classname]#RowItem#s) of SQLContainer can be done similarly to editing the items of any Vaadin container. [classname]#ColumnProperties# of a [classname]#RowItem# will automatically notify SQLContainer to make sure that changes to the items are recorded and will be applied to the database immediately or on commit, depending on the state of the auto-commit mode. [[sqlcontainer.editing.adding]] == Adding items Adding items to an [classname]#SQLContainer# object can only be done via the [methodname]#addItem()# method. This method will create a new [classname]#Item# based on the connected database table column properties. The new item will either be buffered by the container or committed to the database through the query delegate depending on whether the auto commit mode (see the next section) has been enabled. When an item is added to the container it is impossible to precisely know what the primary keys of the row will be, or will the row insertion succeed at all. This is why the SQLContainer will assign an instance of [classname]#TemporaryRowId# as a [classname]#RowId# for the new item. We will later describe how to fetch the actual key after the row insertion has succeeded. If auto-commit mode is enabled in the [classname]#SQLContainer#, the [methodname]#addItem()# method will return the final [classname]#RowId# of the new item. [[sqlcontainer.editing.fetching]] == Fetching generated row keys Since it is a common need to fetch the generated key of a row right after insertion, a listener/notifier has been added into the [classname]#QueryDelegate# interface. Currently only the [classname]#TableQuery# class implements the [classname]#RowIdChangeNotifier# interface, and thus can notify interested objects of changed row IDs. The events fill be fired after [methodname]#commit()# in [classname]#TableQuery# has finished; this method is called by [classname]#SQLContainer# when necessary. To receive updates on the row IDs, you might use the following code (assuming container is an instance of [classname]#SQLContainer#). Note that these events are not fired if auto commit mode is enabled. ---- app.getDbHelp().getCityContainer().addListener( new QueryDelegate.RowIdChangeListener() { public void rowIdChange(RowIdChangeEvent event) { System.err.println("Old ID: " + event.getOldRowId()); System.err.println("New ID: " + event.getNewRowId()); } }); ---- [[sqlcontainer.editing.version-column]] == Version column requirement If you are using the [classname]#TableQuery# class as the query delegate to the [classname]#SQLContainer# and need to enable write support, there is an enforced requirement of specifying a version column name to the [classname]#TableQuery# instance. The column name can be set to the [classname]#TableQuery# using the following statement: ---- tq.setVersionColumn("OPTLOCK"); ---- The version column is preferrably an integer or timestamp typed column in the table that is attached to the [classname]#TableQuery#. This column will be used for optimistic locking; before a row modification the [classname]#TableQuery# will check before that the version column value is the same as it was when the data was read into the container. This should ensure that no one has modified the row inbetween the current user's reads and writes. Note! [classname]#TableQuery# assumes that the database will take care of updating the version column by either using an actual [literal]#++VERSION++# column (if supported by the database in question) or by a trigger or a similar mechanism. If you are certain that you do not need optimistic locking, but do want to enable write support, you may point the version column to, for example, a primary key column of the table. [[sqlcontainer.editing.autocommit]] == Auto-commit mode [classname]#SQLContainer# is by default in transaction mode, which means that actions that edit, add or remove items are recorded internally by the container. These actions can be either committed to the database by calling [methodname]#commit()# or discarded by calling [methodname]#rollback()#. The container can also be set to auto-commit mode. When this mode is enabled, all changes will be committed to the database immediately. To enable or disable the auto-commit mode, call the following method: ---- public void setAutoCommit(boolean autoCommitEnabled) ---- It is recommended to leave the auto-commit mode disabled, as it ensures that the changes can be rolled back if any problems are noticed within the container items. Using the auto-commit mode will also lead to failure in item addition if the database table contains non-nullable columns. [[sqlcontainer.editing.modified-state]] == Modified state When used in the transaction mode it may be useful to determine whether the contents of the [classname]#SQLContainer# have been modified or not. For this purpose the container provides an [methodname]#isModified()# method, which will tell the state of the container to the developer. This method will return true if any items have been added to or removed from the container, as well as if any value of an existing item has been modified. Additionally, each [classname]#RowItem# and each [classname]#ColumnProperty# have [methodname]#isModified()# methods to allow for a more detailed view over the modification status. Do note that the modification statuses of [classname]#RowItem# and [classname]#ColumnProperty# objects only depend on whether or not the actual [classname]#Property# values have been modified. That is, they do not reflect situations where the whole [classname]#RowItem# has been marked for removal or has just been added to the container.