Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trim string field in JPA

Tags:

java

jpa

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?

like image 578
jcreenaune Avatar asked Apr 20 '11 04:04

jcreenaune


People also ask

How to use trim in JPA Query?

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).

How do you trim a string in Java?

Java String trim() MethodThe trim() method removes whitespace from both ends of a string. Note: This method does not change the original string.


1 Answers

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> 

 

like image 91
Sean Patrick Floyd Avatar answered Sep 23 '22 00:09

Sean Patrick Floyd