[英]How to have hibernate use String.intern on attributes
對於某些實體,我們需要將成千上萬個獨立實體的負載永久保存在內存中。 它們的許多屬性來自一組有限的字符串(盡管不足以將其放入枚舉中)。 休眠是否可以將String.intern用於這些屬性以節省空間?
理想情況下,這應該通過注釋來實現,我可以將這些屬性中的每一個或易於更改的屬性放在注釋上,而不會因實現問題而使源代碼過於混亂。
正如您自己建議的那樣,使用JPA屬性轉換器完全可以實現。 您可以在轉換器上使用autoApply = true
在一般級別上執行此操作,也可以在具有@Convert
批注的逐字段級別上進行@Convert
。
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
@Converter(autoApply = true)
public class StringInternConverter implements AttributeConverter<String, String> {
@Override
public String convertToDatabaseColumn(String attribute) {
return attribute;
}
@Override
public String convertToEntityAttribute(String dbData) {
return dbData != null? dbData.intern(): null;
}
}
經過Hibernate 5.2.10的測試,就像魅力一樣!
1)您可以對關鍵屬性使用屬性訪問,並在設置器中內插字符串:
public void setFoo(String foo) {
this.foo = foo != null ? foo.intern() : null;
}
2)如果上述解決方案很繁瑣(您可能有很多此類String
屬性),則可以注冊一個Hibernate攔截器並使用反射來實習所有String
字段:
for (Field field : getDeclaredFields(entity)) {
if (!isStaticOrFinal(field)) {
field.setAccessible(true);
Object value = field.get(entity);
if (value instanceof String) {
field.set(entity, ((String) value).intern());
}
}
}
private List<Field> getDeclaredFields(Object object) {
List<Field> result = new ArrayList<Field>(Arrays.asList(object.getClass().getDeclaredFields()));
for (Class<?> superclass = object.getClass().getSuperclass(); superclass != null; superclass = superclass.getSuperclass()) {
result.addAll(Arrays.asList(superclass.getDeclaredFields()));
}
return result;
}
private boolean isStaticOrFinal(Field field) {
return ((Modifier.STATIC | Modifier.FINAL) & field.getModifiers()) != 0;
}
您可以在onSave
和onLoad
攔截器方法中執行此操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.