Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use UuidProvider based on UUIDv7 #3424

Open
valery-shinkevich opened this issue Jun 27, 2024 · 2 comments
Open

Use UuidProvider based on UUIDv7 #3424

valery-shinkevich opened this issue Jun 27, 2024 · 2 comments
Assignees

Comments

@valery-shinkevich
Copy link

valery-shinkevich commented Jun 27, 2024

Right now, Jmix uses a UuidProvider that generates randomly based UUIDs. This is sufficient for small applications, but for applications where there is a lot of data and UUID is used as primary keys, this causes poor index locality.

Various modifications of UUID generator have been used for a long time to solve this problem. They are all somewhat similar and use time-based UUID generation.

Not so long ago, new UUID formats were introduced, in particular UUIDv7. New UUID Formats - draft
image
This is one of the solutions of poor index locality and already has many implementations for databases and programming languages.
You can also read a lot of articles on this topic, for example:
Goodbye integers. Hello UUIDv7!
Спецификация уникальных идентификаторов UUIDv7 для ключей баз данных и распределенных систем по новому стандарту RFC9562

However, this solution is not suitable for all databases, as far as I know at the moment (I would be glad to be mistaken), MS SQL Server uses a slightly different byte order for storing GUIDs.
Therefore, it would be nice to use the ability to set the generator in the application configuration.

@valery-shinkevich valery-shinkevich added the triage Issue is waiting for triage label Jun 27, 2024
@valery-shinkevich valery-shinkevich changed the title Use different (configurable) UUID generators in UuidProvider, Use different (configurable) UUID generators in UuidProvider, UUIDv7 in particular Jun 27, 2024
@valery-shinkevich
Copy link
Author

I found a good implementation of various UUID versions and made a small test of ordering of different types of UUIDv7.
Add uuid7 and test (WIP)

@gorbunkov gorbunkov added in: core and removed triage Issue is waiting for triage labels Jun 28, 2024
@knstvk
Copy link
Contributor

knstvk commented Jun 28, 2024

Thank you for suggestion, we'll consider changing the default UUID provider to use UUIDv7 in the next feature release.

Currently you can use a custom provider for attributes annotated with @JmixGeneratedValue if you define an appropriate EntityInitializer bean in your project, for example:

package com.company.onboarding;

import io.jmix.core.EntityInitializer;
import io.jmix.core.JmixOrder;
import io.jmix.core.Metadata;
import io.jmix.core.UuidProvider;
import io.jmix.core.entity.EntityValues;
import io.jmix.core.entity.annotation.JmixGeneratedValue;
import io.jmix.core.metamodel.model.MetaClass;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.util.UUID;

@Component
public class MyGeneratedIdEntityInitializer implements EntityInitializer, Ordered {

    private final Metadata metadata;

    public MyGeneratedIdEntityInitializer(Metadata metadata) {
        this.metadata = metadata;
    }

    @Override
    public void initEntity(Object entity) {
        MetaClass metaClass = metadata.getClass(entity);
        metaClass.getProperties().stream()
                .filter(property -> property.getRange().isDatatype()
                        && property.getRange().asDatatype().getJavaClass().equals(UUID.class)
                        && property.getAnnotations().get(JmixGeneratedValue.class.getName()) != null)
                .forEach(property -> {
                    if (EntityValues.getValue(entity, property.getName()) == null) {
                        UUID uuid = UuidProvider.createUuid(); // use your UUID provider
                        EntityValues.setValue(entity, property.getName(), uuid);
                    }
                });
    }

    @Override
    public int getOrder() {
        return JmixOrder.HIGHEST_PRECEDENCE - 10;
    }
}

Pay attention to the order - it must be a lower number (higher precedence) than defined in the GeneratedIdEntityInitializer bean of the framework.

@knstvk knstvk assigned dtaimanov and unassigned knstvk Jun 28, 2024
@knstvk knstvk changed the title Use different (configurable) UUID generators in UuidProvider, UUIDv7 in particular Use UuidProvider based on UUIDv7 Jun 28, 2024
@knstvk knstvk added the size: M label Jun 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

No branches or pull requests

4 participants