Можно ли лениво загружать аннотацию @Formula?
Я использовал аннотацию @Formula
, чтобы использовать ее для получения вычисленных свойств. Мне нужно, чтобы те поля/геттеры, которые были аннотированы с аннотацией @Formula
, должны быть лениво загружены.
Возможно ли это, и если да, то как?
спасибо
Ответы
Ответ 1
Да. Просто аннотируя поля /getter свойства @Formula
@Basic (fetch = FetchType.LAZY) и используйте это ant task, предоставленный hibernate для выполнения инструментария байт-кода для класса сущности. В противном случае загрузка LAZY для свойства @Formula
игнорируется.
Документация содержит информацию о том, как использовать эту задачу ant для работы с инструментами байт-кода.
Ответ 2
Я видел в комментарии, что вы хотели бы достичь этого без инструментария байт-кода. Это может быть достигнуто путем реализации интерфейса FieldHandled
и путем изменения геттеров и сеттеров для ленивого поля.
HBM
<property name="deletable" type="true_false" lazy="true">
<formula>(select something from other tables and such....)</formula>
</property>
JAVA
import org.hibernate.bytecode.javassist.FieldHandled;
import org.hibernate.bytecode.javassist.FieldHandler;
public class Person implements FieldHandled {
/* allows lazy formulas without hibernate bytecode instrumentation */
private FieldHandler fieldHandler;
public FieldHandler getFieldHandler() { return fieldHandler; }
public void setFieldHandler(FieldHandler fieldHandler) { this.fieldHandler = fieldHandler; }
private Boolean deletable;
public void setDeletable(Boolean deletable) {
if(fieldHandler!=null)
fieldHandler.writeObject(this, "deletable", this.deletable, deletable);
this.deletable = deletable;
}
public Boolean getDeletable() {
if(fieldHandler!=null)
return (Boolean)fieldHandler.readObject(this, "deletable", deletable);
return deletable;
}
}
Другой пример можно найти здесь. Но это ленивая загрузка отношений "один к одному".
Ответ 3
Я пытался с BytecodeEnhancement (Плагин Maven), но не работает. Итак, я сделал это:
-
Создайте класс (FooFormula.java), сопоставьте его с таблицей с двумя полями, одно для @id и другое для @Formula.
@Entity
@Table(name = "BAR_TABLE")
public class FooFormula implements Serializable {
private Long idBarTable;
private Long formula;
public FooFormula() {
super();
}
public FooFormula(String idBarTable) {
super();
this.idBarTable = idBarTable;
}
@Id
@Column(name = "ID_BAR_TABLE", unique = true, nullable = false, length = 20)
public Long getIdBarTable() {
return this.sitidBarTableCodigo;
}
public void setIdBarTable(Long idBarTable) {
this.idBarTable = idBarTable;
}
@Formula("(SELECT 1 from DUAL)")
public Long getFormula() {
return formula;
}
public void setFormula(Long formula) {
this.formula = formula;
}
}
-
Добавьте этот новый класс (Bar.java) в качестве поля вашей сущности.
@Entity
@Table(name = "BAR_TABLE")
public class Bar implements Serializable {
private Long idBarTable;
private Long somOtherColumn;
private FooFormula fooFormula;
public Bar() {
super();
}
public Bar(String idBarTable) {
super();
this.idBarTable = idBarTable;
}
@Id
@Column(name = "ID_BAR_TABLE", unique = true, nullable = false, length = 20)
public Long getIdBarTable() {
return this.sitidBarTableCodigo;
}
public void setIdBarTable(Long idBarTable) {
this.idBarTable = idBarTable;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ID_BAR_TABLE", nullable = false, insertable=false, updatable=false)
public FooFormula getFooFormula() {
return fooFormula;
}
public void setFooFormula(FooFormula fooFormula) {
this.fooFormula = fooFormula;
}
}