SQLContainer.getItem(...) with a composite key

Hello,

I’m writing a log view system for an application which uses logback and logs to sql database.

I have the primary table which is
logging_event
which has like a message string and its key
event_id
.
Another table is
logging_event_propery
which has the composite key (
logging_event.event_id
,
mapped_key
). This table contains properties for all loglines such as which server it was on and the name of the thread and such.

I have done an sqlContainer with a TableQuery which fetches the
logging_event
table.

Something like:

final SQLContainer logContainer = new SQLContainer(new TableQuery("logging_event", getConnectionPool(), new MSSQLGenerator()));
final SQLContainer logEventPropertyContainer = new SQLContainer(new TableQuery("logging_event_property", getConnectionPool(), new MSSQLGenerator()));

I would like to add a column in the table which shows logContainer which contains the hostname of the server. This property is located in logEventProperyContainer. The way I thought best to do this was to add a generated column to the table.

But how do I do logEventPropertyContainer.getItem(...) when the key is a composite key consisting of two fields?

I was hoping to do this in Vaadin but worst case I’ll have to create a view for it in the database.

Best regards,
Kalle Stropp (aka Gustav)

Hi,

SQLContainer should use instances of com.vaadin.data.util.sqlcontainer.RowId for the item ID. So you should be able to get by with something like this:

logEventPropertyContainer.getItem(new RowId(firstKeyPart, secondKeyPart));

where firstKeyPart and secondKeyPart are obviously the two values of your composite key. Also make sure that the order of the values is correct (this should be the same as the definition in the DB).

Thank you for your reply, Teppo.

Unfortunately this did not work. I tried looking trough the Vaadin source code to understand what to do instead, because RowId seem to be involved in some way. But I was unsuccessful.

Am I just doing it wrong?; SHOULD it work like this? Or was it just a guess?

I tried these without success:

logEventPropertyContainer.getItem(new RowId("6", "HOSTNAME"));
logEventPropertyContainer.getItem(new RowId(new BigInt(6), "HOSTNAME"));

Hi,

it should (and has) worked this way, see e.g. this thread
https://vaadin.com/forum#!/thread/1267746
. If this does not work for you, please try calling SQLContainer.getItemIds() somewhere in your code (returns all item ids), and examine the result with your debugger. That way you should at least be able to determine the correct order and types (and even values) of the PK columns.

Hi,

Good idea!

RowId next = (RowId) logEventPropertyContainer.getItemIds().iterator().next();
System.out.println(Arrays.toString(next.getId()));
for (Object k : next.getId()) {
    System.out.println(k.getClass());
}

Produced:
[1, HOSTNAME]

class java.lang.Long
class java.lang.String

logEventPropertyContainer.getItem(new RowId(new Long(1), "HOSTNAME")); Gave me the data i needed. Lets hope the BigInt in the database never gets bigger than what a long can hold :slight_smile:

I also tried making a view for it. The view worked fine but Vaadin was unable to use TableQuery on a view. It complained that the view did not have any primary key constraints. But the view is not needed for now since this seem to work instead. I guess a ViewQuery() would have been nice :slight_smile:

Thanks again!

…And as I finally got it to work with a generated column which fetches from the SQLContainer I find out that this will not work. It is way too slow. Loading 100 rows takes half a minute. I guess I’ll have to aim for that view instead anyway.

I guess a FreeFormQuery is the easiest solution.

Yes, to use a view you need to implement a FreeFormQuery. By the way, I’m quite sure the min/max values of BigInt and java’s Long are the same so there should be no worries about overflow.