我有一个db表,其数据类型为char(20).我不允许将其更改为varchar.
我正在编写映射到此表的JPA实体.我希望在我的实体类中表示此列的字符串字段始终包含修剪后的值,而不是填充db中存在的空格的20个字符值.
我看不到任何简单的方法来做到这一点.(注释会晃动!).目前我只是从我的getter()返回一个修剪过的值,但这感觉就像一个kludge.
谷歌搜索没有提供任何帮助.有任何想法吗?
Sea*_*oyd 25
或者您可以使用生命周期注释:
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
如果在多个实体上发生这种情况,您可以创建自定义注释并编写专用的EntityListener.
注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Trim {}
Run Code Online (Sandbox Code Playgroud)
倾听者
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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在注释所有相关的String字段,@Trim并将监听器注册为persistence.xml中的默认实体监听器:
<persistence-unit ..>
<!-- ... -->
<default-entity-listeners>
com.somepackage.TrimListener
and.maybe.SomeOtherListener
</default-entity-listeners>
</persistence-unit>
Run Code Online (Sandbox Code Playgroud)
pat*_*ckd 16
接受的答案(使用JPA实体监听器/ @Trim注释)是一个危险的答案. 在检索到的实体上调用setter似乎将实体标记为脏.当我在root实体级别(使用Spring3/hibernate)自己尝试这个时,它会触发大量对相关实体的无关更新,否则这些更新在事务期间不会被修改.这是一个真正的混乱的生产,并追溯到这是原因需要时间.
最后,我选择采用更直接的方法手动按需手动修剪每个字段(在自定义实体到域映射器中,或在实体getter中),类似于Edwin的答案.
jfa*_*ior 10
这是一个老问题,但对我来说得到答案非常有用。就我而言,最简单的方法是创建一个简单的“javax.persistence.Converter”,如下所示:
@Converter
public class StringTrimConverter implements AttributeConverter<String, String> {
@Override
public String convertToDatabaseColumn(String attribute) {
return attribute;
}
@Override
public String convertToEntityAttribute(String dbData) {
return dbData.trim();
}
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它:
@Entity
@Table(name = "ViewAddress")
public class PostalAddress extends DbObject {
@Convert(converter = StringTrimConverter.class)
private String street;
@Convert(converter = StringTrimConverter.class)
private String number;
(...)
Run Code Online (Sandbox Code Playgroud)
它工作得很好。
| 归档时间: |
|
| 查看次数: |
25967 次 |
| 最近记录: |