I have a db table with column of datatype char(20). I'm not allowed to change it to a varchar.
I'm writing a JPA entity mapped to this table. I would like the string field representing this column in my entity class to always contain the trimmed value, not the 20-character value padded with spaces that exists in the db.
I can't see any easy way to do this. (an annotation would rock!). At the moment I'm just returning a trimmed value from my getter(), but this feels like a kludge.
A google search is offering no help on this. Any ideas?
TRIM([[LEADING|TRAILING|BOTH][char] FROM] string) The TRIM function trims the specified character from a string. The keywords LEADING, TRAILING, BOTH are all optional, if not specified BOTH is assumed. If the 'char' to be trimmed is not specified, it will be assumed to be space (or blank).
Java String trim() MethodThe trim() method removes whitespace from both ends of a string. Note: This method does not change the original string.
Or you can use lifecycle annotations:
@Entity public class MyEntity { @PostLoad protected void repair(){ if(myStringProperty!=null)myStringProperty=myStringProperty.trim(); } private String myStringProperty; public String getMyStringProperty() { return myStringProperty; } public void setMyStringProperty(String myStringProperty) { this.myStringProperty = myStringProperty; } }
If this occurs on multiple entities you can create a custom annotation and write a dedicated EntityListener.
Annotation
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Trim {}
Listener
public class TrimListener { private final Map<Class<?>, Set<Field>> trimProperties = new HashMap<Class<?>, Set<Field>>(); @PostLoad public void repairAfterLoad(final Object entity) throws Exception { for (final Field fieldToTrim : getTrimProperties(entity.getClass())) { final String propertyValue = (String) fieldToTrim.get(entity); if (propertyValue != null) fieldToTrim.set(entity, propertyValue.trim()); } } private Set<Field> getTrimProperties(Class<?> entityClass) throws Exception { if (Object.class.equals(entityClass)) return Collections.emptySet(); Set<Field> propertiesToTrim = trimProperties.get(entityClass); if (propertiesToTrim == null) { propertiesToTrim = new HashSet<Field>(); for (final Field field : entityClass.getDeclaredFields()) { if (field.getType().equals(String.class) && field.getAnnotation(Trim.class) != null) { field.setAccessible(true); propertiesToTrim.add(field); } } trimProperties.put(entityClass, propertiesToTrim); } return propertiesToTrim; } }
Now annotate all relevant String fields with @Trim
and register the Listener as default entity listener in your persistence.xml:
<persistence-unit ..> <!-- ... --> <default-entity-listeners> com.somepackage.TrimListener and.maybe.SomeOtherListener </default-entity-listeners> </persistence-unit>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With