Можно ли лениво загружать аннотацию @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), но не работает. Итак, я сделал это:

  1. Создайте класс (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;
      }
    }
    
  2. Добавьте этот новый класс (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;
      }
    }