我想让我的实体实现某个接口,返回id:
public interface IdentifiableEntity<T extends Comparable<T>> {
public T getIdentifier();
}
但是如果我这样做并且实体是延迟加载的,getIdentifier()
初始化代理(并导致单独的选择)。这是一个示例实体:
@Entity
public class AppFile implements IdentifiableEntity<Long> {
@Id
@GeneratedValue
private Long id;
public Long getIdentifier() {
return id;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
...
}
有没有办法告诉Hibernate / JPA getIdentifier()
只访问众所周知的ID而不需要初始化代理?
我已经找到了:
getId()
将不会初始化代理。@Access(AccessType.PROPERTY)
上使用private Long id;
,它将表现为1.无需在属性级别注释所有内容。更新 1.和2.都不满足我的要求,即:
getIdentifier()
返回没有代理初始化的ID id
不会更改其名称(因为有很多现有的JPQL语句)。答案 0 :(得分:0)
getId()
方法初始化代理,只需要重定向getIdentifier()
方法。
public Long getId() {
return getIdentifier();
}
答案 1 :(得分:0)
即使您在字段上使用注释,也可以使用Java Reflection API直接访问id值。在这里,我使用org.easytesting fest-reflect API(Reflection API的一个薄包装器)来缩短代码。 proxy.handler.id下的id值。 我的示例是具有ManyToOne到部门(潜在代理)的员工。 就我而言,id(s)总是很长......
public Long extractIdFromDepartment(Employee employee) {
Long idDepartment = null;
Department departement = employee.getDepartment();
Boolean isNotProxy = Persistence.getPersistenceUtil().isLoaded(departement);
if (isNotProxy) {
// here, department is not a proxy
// a direct access is always ok
idDepartment = departement.getId();
} else {
// here department IS a proxy
// works in all cases : with Hibernate/JPA annotations on getters or fields.
javassist.util.proxy.MethodHandler handler = Reflection.field("handler")
.ofType(javassist.util.proxy.MethodHandler.class).in(departement).get();
java.io.Serializable idDep = Reflection.field("id").ofType(java.io.Serializable.class).in(handler).get();
if (idDep instanceof Long) {
idDepartment = (Long) idDep;
}
}
return idDepartment;
}
答案 2 :(得分:0)
那么4年后,但这将是解决方案:
@Entity @Access(AccessType.FIELD) 公共类AppFile实现IdentifiableEntity {
@Id
@GeneratedValue
@Access(AccessType.PROPERTY)
private Long id;
public Long getId(){
return id;
}
现在在实体上调用getId()
将不会初始化其代理。