Truncate String in an @Entity class prevents SQL exception when inserting a long string

1 week ago 8
ARTICLE AD BOX

This topic has been answered multiple times here and there, but none of the suggested solutions look elegant and requires too much boilerplate code + work to add the suggested solutions into your project.

My solution works fine and automatically based on the length definition of the @Column annotation: @Column(name = "address", length = 50) but it requires two annotations to be added into your @Entity class.

I wonder if there is an official Java library that can solve this problem with zero code and requires only one annotation to be addedt into my project.

I use Mapstruct and Lombok.

Mapstruct converts my POJOs (coming from REST) into entities, so a solution that shortens the value of string variables in the entity during the Mapstruct conversion could work for me as well. Unfortunately, I could not find a simple solution for Mapstruct.

Another solution that came to mind is to modify the Lombok @Setter annotation in some way to cut the string content when the set methods are called. However, I could not find a convenient and simple solution to implement this. Plus POJOs do not know the max length of the Strings, it is only known in classes annotated with @Entity and @Column.

This is my solution, which requires adding two annotations, but I want to replace it with an "official" library, if exists:

@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Shorten { int length() default 255; }

Implementation:

import jakarta.persistence.Column; import jakarta.persistence.PrePersist; import jakarta.persistence.PreUpdate; import java.util.Objects; public class StringShortenerListener { @PrePersist @PreUpdate public void shortenStrings(Object entity) { for (var field : entity.getClass().getDeclaredFields()) { if (field.isAnnotationPresent(Shorten.class)) { field.setAccessible(true); try { Column columnAnnotation = field.getAnnotation(Column.class); int maxLength = field.getDeclaredAnnotation(Column.class).length(); if (Objects.nonNull(columnAnnotation)) { int length = columnAnnotation.length(); if (length > 0) { // the length attribute exists in the @Column annotation String value = (String) field.get(entity); if (value != null && value.length() > maxLength) { field.set(entity, value.substring(0, maxLength)); } } } } catch (IllegalAccessException e) { e.printStackTrace(); } } } } }

Usage:

@Entity @EntityListeners(StringShortenerListener.class) @Table(name = "customer") @Data public class CustomerEntity { @Column(name = "name", length = 48, nullable = false) @Shorten private String name; }
Read Entire Article