This is an internal documentation. There is a good chance you’re looking for something else. See Disclaimer.

Custom java types

Per default Hibernate can map all primitive types (and its wrapper classes) as well as references to other entities. For all other classes that need to be mapped to the database a JavaType must be implemented. The java type contains the logic how a specific object should be read and written.

For example the Login class is mapped with a custom java type (LoginJavaType).

There are two ways to register a new java type:

It can be registered with a bootstrap contribution (see Participate in the bootstrap process). This way should be used if there is a distinct object which should be mapped (for example Login):

classLoaderService.addContribution(TypeContributor.class, ((typeContributions, serviceRegistry) -> {
    JdbcTypeRegistry jdbcTypeRegistry = typeContributions.getTypeConfiguration().getJdbcTypeRegistry();
    typeContributions.getTypeConfiguration().getBasicTypeRegistry().register(
        new StandardBasicTypeTemplate<>(
            jdbcTypeRegistry.getDescriptor(Types.VARCHAR), new LoginJavaType(), Login.class.getName()
        )
    );
}));

The alternative is to bind the java type to a field type (like phone) using a contribution:

@Component
public class PhoneJavaTypeContribution extends JavaTypeFieldContribution<PhoneJavaType> {

    private final L10N l10n;
    private final PhoneFormatter phoneFormatter;

    public PhoneJavaTypeContribution(L10N l10n,
                                     PhoneFormatter phoneFormatter) {
        this.l10n = l10n;
        this.phoneFormatter = phoneFormatter;
    }

    @Override
    public String getTypeName() {
        return "phone";
    }

    @Override
    protected Class<PhoneJavaType> javaTypeClass() {
        return PhoneJavaType.class;
    }

    @Override
    protected PhoneJavaType javaType() {
        return new PhoneJavaType(l10n, phoneFormatter);
    }
}

Simple java types

Most java types are relatively simple and only map between a string or number and an object:

phone type

The PhoneJavaType is applied for all field of the virtual phone type. This java type does not convert between different objects, but formats the phone number using the PhoneFormatter whenever a phone value is written to the database.

html type

Like the PhoneJavaType, the HtmlJavaType does not convert between different objects but does some string formatting for html fields.

The formatting behaviour can be contributed using a HtmlJavaTypeExtension. Currently there is only the PreserveFreemarkerOperatorsHtmlJavaTypeExtension which handles escaping in freemarker expressions.

binary type

The BinaryJavaType handles the Binary class. The column of a binary field contains the hash code of the binary and references the _nice_binary table.

In addition to the mapping of the hash code this java type also calls the configured BinaryAccessProvider which stores the binary data if necessary.

Java types are also used to map query parameters. If a Binary object is used as a query parameter, it should obviously not be attempted to write it to the binary data store! Therefore the binary content is only saved if Binary#mayBeStored() returns true. If a hash code is used as a query parameter for a binary field, the string is converted to a BinaryQueryParameter by the StringToBinaryParameterConverter. BinaryQueryParameter#mayBeStored() returns false so it can safely be used in queries.

See chapter Large objects for more details about large objects.

compressed-text type

The CompressedTextJavaType is a sub-type of the string type. It compresses and decompresses the string data when writing and reading the field from the database. Zstd compression is used, the compression level can be configured using the persist.core.zstd.compression.level property (default value is 19).

Note

This is useful for storing large text fields, but keep in mind that the content of the string cannot be used in a query, as only the compressed data is available on the database.