Dynamic Entities

I think I asked this question in the past and was told that this would be put in the roadmap. So I wanted to know where this feature stands.
But here’s what I’m trying to accomplish:

  • a user issues a query to an external system. That system will return the results in a CSV file with headers.
  • My code will parse that file, and create an entity from the file header.
  • it will then create a datasource, fill it with the csv data, and display it in a table.
    So that’s why I think I would need to create a dynamic entity.

Right now, this is what I’m doing.
I have created a web companion class where I dynamically create a vaadin table and fill it with data and display that table on my screen.
The problem with this approach is that 1) I noticed that my code running in the web companion class is slow. I don’t know if this is because I’m unwrapping component or what, 2) I cannot take advantage of your generic filter, 3) the table is slow to generate.

So I was just curious to hear if the dynamic entity feature was still on the roadmap or if you have a novel solution to my issues?
Thanks.

2 Likes

Hi Francis,

Yes, we have implemented a mechanism that should suit your needs in the platform release 6.1.
See JavaDocs for KeyValueEntity and KeyValueCollectionDatasourceImpl and the following code example:


KeyValueCollectionDatasourceImpl ds = new DsBuilder().buildCollectionDatasource(KeyValueCollectionDatasourceImpl.class);
ds.addProperty("prop1").addProperty("prop2").addProperty("prop3");

KeyValueEntity entity;

entity = new KeyValueEntity();
entity.setValue("prop1", "val1");
entity.setValue("prop2", "val2");
entity.setValue("prop3", "val3");
ds.includeItem(entity);

entity = new KeyValueEntity();
entity.setValue("prop1", "val11");
entity.setValue("prop2", "val21");
entity.setValue("prop4", "val31");
ds.includeItem(entity);

Table table = componentsFactory.createComponent(Table.class));
table.setWidth("100%");
table.setHeight("100%");
table.setDatasource(ds);
table.setColumnCaption("prop1", "Property 1");
table.setColumnCaption("prop2", "Property 2");
table.setColumnCaption("prop3", "Property 3");

add(table);

You can also use KeyValueGroupDatasourceImpl or KeyValueHierarchicalDatasourceImpl if you want to display data in GroupTable or TreeTable respectively. However, Filter component will not work with this in-memory data, because it is designed for working with JPQL queries and filtering on the database level.
This approach should simplify your code and allow you to use GroupTable, but I doubt that it will work faster than native Vaadin table. In fact, the Vaadin table is under the hood anyway.

that is really good to know and very informative and I will keep that mind.
The example above is for creating in-memory entities. If I wanted to use the generic filter on a table, I was wondering if there was a way to programatically create a dynamic “persistent” entity. This way, I could I could populate a table with data linked to that entity and the filtering should work.
Are my assumptions correct?

Unfortunately, you cannot create a persistent entity at runtime, because it requires reconfiguration of the ORM persistence unit on the fly, which is hardly possible.

If you want to store your imported data in the database, I would suggest the following approach:

  • Create a new table for each import or for each type of file, where type is defined by the set of columns
  • Create an entity to store the name and type of imported file
  • Create a screen with dynamically created KeyValueGroupDatasourceImpl and GroupTable
  • The screen should allow a user to select an entity that defines an imported file and its DB table. After that, the screen shows a custom filter containing all fields from the selected table. After applying the filter, the screen invokes a service, that generates an SQL query by the filter, executes it and returns a set of KeyValueEntity to the screen.

This will allow users to filter data, use grouping table, and you will even be able to implement paging for loading data if the dataset is large.

The most interesting part of such implementation is probably the custom filter and SQL generator. It depends on what data types and conditions (equals, contains, etc.) you want to handle. But as your data is plain (no references), code should not be complicated.

Hi @knstvk
I am trying to fill a table in the same way but my problem is that The entity class is not an Entity , but it is a DTO that is filled from calling an API.

I am not finding anyway to fill the table by anything but persistent Entity that extends Entity while I don’t have this in my case.1

Is what I want doable in cuba please.