修剪 JPA 中的字符串字段
我有一个数据库表,其中的列数据类型为char(20)。我不允许将其更改为varchar。
我正在编写一个映射到此表的 JPA 实体。我希望在我的实体类中表示此列的字符串字段始终包含修剪后的值,而不是用数据库中存在的空格填充的20个字符的值。
我看不出有任何简单的方法来做到这一点。(注释会摇滚!目前,我只是从我的 getter() 返回一个修剪过的值,但这感觉就像是一个笨拙。
谷歌搜索对此没有任何帮助。有什么想法吗?
我有一个数据库表,其中的列数据类型为char(20)。我不允许将其更改为varchar。
我正在编写一个映射到此表的 JPA 实体。我希望在我的实体类中表示此列的字符串字段始终包含修剪后的值,而不是用数据库中存在的空格填充的20个字符的值。
我看不出有任何简单的方法来做到这一点。(注释会摇滚!目前,我只是从我的 getter() 返回一个修剪过的值,但这感觉就像是一个笨拙。
谷歌搜索对此没有任何帮助。有什么想法吗?
或者,您可以使用生命周期注释:
@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;
}
}
如果这种情况发生在多个实体上,则可以创建自定义批注并编写专用的 EntityListener。
注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Trim {}
听者
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;
}
}
现在,使用注释所有相关的 String 字段,并将监听器注册为持久性中的默认实体监听器.xml:@Trim
<persistence-unit ..>
<!-- ... -->
<default-entity-listeners>
com.somepackage.TrimListener
and.maybe.SomeOtherListener
</default-entity-listeners>
</persistence-unit>
接受的答案(使用JPA实体侦听器/@Trim注释)是一个危险的答案。对检索到的实体调用 setter 似乎会将该实体标记为脏。当我在根实体级别(使用Spring3 / hibernate)自己尝试时,它触发了对相关实体的大量无关更新,否则这些更新在事务期间不会被修改。这在生产中是一个真正的混乱,追踪它的原因需要时间。
最后,我选择采用更直接的方法,即按需手动修剪每个字段(在自定义实体到域映射器中,或在实体获取器中),类似于Edwin的答案。