【发布时间】:2012-04-21 15:54:12
【问题描述】:
我使用@Formula 注释来获取计算属性。我需要的是那些带有@Formula 注释的字段/getter 应该被延迟加载。
这甚至可能吗?如果可以,怎么办?
谢谢
【问题讨论】:
标签: hibernate jakarta-ee annotations
我使用@Formula 注释来获取计算属性。我需要的是那些带有@Formula 注释的字段/getter 应该被延迟加载。
这甚至可能吗?如果可以,怎么办?
谢谢
【问题讨论】:
标签: hibernate jakarta-ee annotations
是的。只需用@Basic(fetch=FetchType.LAZY) 注释@Formula 属性的字段/getter,并使用hibernate 提供的ant task 来为实体类进行字节码检测。否则,@Formula 属性的 LAZY 加载将被静默忽略。
documentation 包含有关如何使用此 ant 任务进行字节码检测的信息。
【讨论】:
maven-antrun-plugin插件,它可以在Maven中运行Ant任务。见:doginpool.blogspot.com/2012/03/…
org.hibernate.tool.instrument.cglib.InstrumentTask 已弃用,请改用org.hibernate.tool.instrument.javassist.InstrumentTask。来源:docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/tool/…
我在评论中看到您希望在没有字节码检测的情况下实现这一目标。这可以通过实现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,您知道吗?您使用的是哪个休眠版本?
我尝试使用BytecodeEnhancement (Maven Plugin),但不起作用。 所以我做了这个:
创建一个类(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;
}
}
使用@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;
}
}
【讨论】: