UUIDAttributeConverter.convertToDatabaseColumn is not called at all

I wrote an attribute converter to use binary 16 instead of char 36 in mysql for primery keys. I added this file to project:

package com.company.jmix02;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.nio.ByteBuffer;
import java.util.UUID;

@Converter(autoApply = false)
public class UUIDAttributeConverter implements AttributeConverter<UUID, byte[]> {

    @Override
    public byte[] convertToDatabaseColumn(UUID uuid) {
        if (uuid == null) return null;
        byte[] buffer = new byte[16];
        ByteBuffer bb = ByteBuffer.wrap(buffer);
        bb.putLong(uuid.getMostSignificantBits());
        bb.putLong(uuid.getLeastSignificantBits());
        return buffer;
    }

    @Override
    public UUID convertToEntityAttribute(byte[] bytes) {
        if (bytes == null) return null;
        ByteBuffer bb = ByteBuffer.wrap(bytes);
        long high = bb.getLong();
        long low = bb.getLong();
        return new UUID(high, low);
    }
}

and even added a UUIDDataType:

package com.company.jmix02;

import io.jmix.core.metamodel.annotation.DatatypeDef;
import io.jmix.core.metamodel.annotation.Ddl;
import io.jmix.core.metamodel.datatype.Datatype;

import javax.annotation.Nullable;
import java.text.ParseException;
import java.util.Locale;
import java.util.UUID;


@DatatypeDef(
        id = "UUID",
        javaClass = UUID.class,
        defaultForClass = true
)
@Ddl("BINARY(16)")
public class UUIDDataType  implements Datatype<UUID> {
    @Override
    public String format(@Nullable Object value) {
        if(value instanceof UUID)
            return ((UUID) value).toString();
        return null;
    }

    @Override
    public String format(@Nullable Object value, Locale locale) {
        return format(value);
    }

    @Nullable
    @Override
    public UUID parse(@Nullable String value) throws ParseException {
        return UUID.fromString(value);
    }

    @Nullable
    @Override
    public UUID parse(@Nullable String value, Locale locale) throws ParseException {
        return parse(value);
    }
}

and in entity:

   @Convert(converter = UUIDAttributeConverter.class)
    @Column(name = "ID", nullable = false, columnDefinition = "BINARY(16)")
    @Id
    private UUID id;

but when saving the entity , it throws an exception because convertToDatabaseColumn is not called at all.

Thank you for pointing out the problem!

It turned out that UUID type has a special handling in the framework which is hardly possible to override in applications. We’ll try to make it more flexible in the next feature release, see https://github.com/jmix-framework/jmix/issues/868

At the moment, if you are concerned with the performance of UUID keys on MySQL, I would recommend using Long keys.

Regards,
Konstantin

Thanks Konstantin, I found out that JMix supports uuid type in Postgresql . In MySql 8(which is old enough) we have uuid type too. Why not support it natively?

Regards

Because we started with MySQL 5 :slight_smile:
Perhaps it’s time to change, thanks for reminding!