No corresponding meta object name after restoring table

0
After restoring a table (via SQL Server) to database B from database A (A is an old backup of B, only difference was the modulename), strange behavior appears. In a microflow, when retrieving the first record from this entity, the following error appears: The provided entity id 389 has no corresponding meta object name. When having a search in database A on the table mendixsystem$entityidentifier, there is a record with short_id 389. This entityidentifier.id corresponds to the id in mendixsystem$entity. The entityname is the table which have been restored, so this makes sense. When changing the shortid in database B to 389, the error on the retrieve is resolved. But, I am worried the old shortid has usage somewhere else. Question 1: Are there any side effects of the change I did? Question 2: What is the right way to solve the problem with the missing meta object name?
asked
1 answers
2

The Mendix runtime server keeps a meta administration of the entity tables, to be able to handle complex changes during synchronization while preserving data. If you just copy objects from 1 database to the other, even if they have the same model, the 16 bit part (of the 64 bit identifier of an object) that points at the TYPE of entity will probably not point at the correct entity type. The exception you got would be the exception you get in such a case.

That said, in your case I would expect this to work because you are saying that it's an old copy of the database with just a changed module name. The good thing about these entity ids is that they actually don't depend on the name given in the model. That does require however that it is really the the same entity that was created once, not just an entity that was deleted somewhere and then recreated in another module with the same name. Moving an entity to a new domain model would work, same as renaming the module.

If you check the database and object identifiers in this entity table of this type look completely different between the 2 databases, then what probably happened is that the entity did not have the same internal identifier, possibly because it was recreated.

For further reading, here's a bit on how the id mechanism works. I wrote this earlier and was thinking of putting it in a blog post as a follow up on my article at https://www.mendix.com/blog/synchronizing-database-domain-model-magical-tale/


How does the id mechanism work in Mendix (4, 5 and the foreseeable future)

Composition and why

The actual identifiers you will see in an id column of an entity table are made up of 48 bits (least significant) which are just an increasing unique number AND an additional 16 bits (most significant) indicating what entity type they actually are. This 16 bit value is constant for a certain entity in a specific database.

This 16 bit part is useful for inheritance as we implemented it. There are a few ways in which you can define inheritance in a database. They all have their benefits and downsides and it's beyond the scope of this explanation to describe them all. For further reading, check out http://martinfowler.com/eaaCatalog/singleTableInheritance.html, http://martinfowler.com/eaaCatalog/concreteTableInheritance.html and http://martinfowler.com/eaaCatalog/classTableInheritance.html. In our datastorage component we opted for the Class Table Inheritance architecture, meaning that for every Entity in your domain model a table is created, but attributes of superentities are not duplicated in all the tables of the subentities.

Now consider the case when you suddenly start inheriting from another entity but you already have data, you can imagine you have a Car entity with object ids 1 to 1000000 and a Vehicle entity with object ids 1 to 1500000. If you would not have the 16 bit entity id part and you want to let Car inherit from Vehicle, you would have to renumber all the identifiers in the Car entity so they are not conflicting with the ones in Vehicle, because in Class Table Inheritance the identifiers of Car will also exist in the Vehicle table. This renumbering is actually how we used to do this but can cause long database synchronization processes.

Another benefit of having the entity identifier within the bigger id is that the outside world and most importantly our web client always knows exactly which id belongs to which entity. In older versions we did not store the entity identifier inside the id of an object and in this scenario the identifiers that were exposed to the client would sometimes change between restarting the runtime server, for example if there were domain model changes. This is not usually a problem unless you want to be able to refer to specific objects between different clients and different runtime servers operating on the same database. This is needed for high availability (fail-over) and horizontal scaling.

Obtaining identifiers

To support transient objects and increase performance, we no longer automatically insert objects into the database anymore when creating them since Mendix 4. Obviously we still need unique identifiers for objects which is why we reserve batches of identifiers up front.

Multiple Mendix Runtime servers with the same application can operate on a single database so this is all done neatly in transactions such that one server can claim a set of identifiers and immediately updates the table administrating these, the next server will never claim the same range.

These identifiers are currently reserved in sets of 100 at a time and their current number is kept in a special system table. When identifiers are about to run out, we can do an asynchronous database query claiming some more identifiers. If a runtime server stops then the ids not spent are basically lost, which is not an issue since the object id part of the identifiers is 48 bits.

The system table holding these identifiers is called mendixsystem$entityidentifier. It has the columns id, shortid and objectsequence. Every entity in your application has a row in this table.

  1. The id column here contains a GUID, this is the id that the entity has in your application model (the mpr file) that never changes and is the same for all database instances. To actually get to know the entity name in your domain model and the table the entity is stored in, you can look it up in the mendixsystem$entity table that contains the same id column and also an entityname and tablename column.
  2. The short_id column is generated for this specific database instance and represents the 16 most significant bits of the 64 bit identifier.
  3. The object_sequence column holds the next available number that can be used for the 48 bit part of an object identifier. When claiming identifiers, this number is bumped by 100 by the runtime server.
answered