【问题标题】:Is it possible to make @Formula annotation lazily loaded?是否可以延迟加载 @Formula 注释?
【发布时间】:2012-04-21 15:54:12
【问题描述】:

我使用@Formula 注释来获取计算属性。我需要的是那些带有@Formula 注释的字段/getter 应该被延迟加载。

这甚至可能吗?如果可以,怎么办?

谢谢

【问题讨论】:

    标签: hibernate jakarta-ee annotations


    【解决方案1】:

    是的。只需用@Basic(fetch=FetchType.LAZY) 注释@Formula 属性的字段/getter,并使用hibernate 提供的ant task 来为实体类进行字节码检测。否则,@Formula 属性的 LAZY 加载将被静默忽略。

    documentation 包含有关如何使用此 ant 任务进行字节码检测的信息。

    【讨论】:

    【解决方案2】:

    我在评论中看到您希望在没有字节码检测的情况下实现这一目标。这可以通过实现FieldHandled 接口和修改惰性字段的getter 和setter 来实现。

    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;
    }
    }
    

    另一个例子可以找到here。但这是延迟加载一对一的关系。

    【讨论】:

    • 我尝试了您的解决方案,但我在org.hibernate.engine.spi.EntityEntry.isUnequivocallyNonDirty(EntityEntry.java:314) 上得到了一个 NPE,您知道吗?您使用的是哪个休眠版本?
    • @Kakawait 抱歉,我不太清楚。我不久前写了这段代码,并相信它是 3.x(其中 x 未知)
    • 这对我有用:不要为 setter 使用 fieldHandler。这是一个公式,在 DB 中无需设置任何内容
    • 但是我有这个问题:stackoverflow.com/questions/31701761/…hibernate 不想更新 FieldHandled 实体上的常规字段,
    • 在 Hibernate 4.3.11 中为我工作,很好的解决方案。
    【解决方案3】:

    我尝试使用BytecodeEnhancement (Maven Plugin),但不起作用。 所以我做了这个:

    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. 使用@ManyToOne 和@JoinColumn 将此新类 (FooFormula.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;
        }
      }
      

    【讨论】:

      猜你喜欢
      • 2014-07-20
      • 1970-01-01
      • 2018-02-15
      • 2016-11-05
      • 2017-12-31
      • 1970-01-01
      • 1970-01-01
      • 2018-08-23
      • 1970-01-01
      相关资源
      最近更新 更多