Zec*_*tes 8 java orm proxy hibernate lazy-loading
我有Hibernate Entities看起来像这样(getters和setter被遗漏):
@Entity
public class EntityA {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
private EntityB parent;
}
@Entity
public class EntityB extends SuperEntity {
@OneToMany(mappedBy = "parent")
@Fetch(FetchMode.SUBSELECT)
@JoinColumn(name = "parent_id")
private Set<EntityA> children;
}
@MappedSuperclass
public class SuperEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private long itemId;
}
Run Code Online (Sandbox Code Playgroud)
当我查询EntityA时,它加载正常,父关联被Hibernate代理替换(因为它是Lazy).如果我想访问父母的id,我执行以下调用:
EntityA entityA = queryForEntityA();
long parentId = entityA.getParent().getItemId();
Run Code Online (Sandbox Code Playgroud)
据我所知,调用不应该向数据库进行往返,因为Id存储在EntityA表中,并且代理应该只返回该值.但是,在我的情况下,这将生成一个SQL语句,该语句提取EntityB,然后才返回Id.
我该如何调查这个问题?导致这种错误行为的可能原因是什么?
Pas*_*ent 10
As I understand that call should NOT make a roundtrip to the database, as the Id is stored in the EntityA table, and the proxy should only return that value.
Use property access type. The behavior you're experiencing is a "limitation" of field access type. Here is how Emmanuel Bernard explained it:
That is unfortunate but expected. That's one of the limitations of field level access. Basically we have no way to know that getId() indeed only go and access the id field. So we need to load the entire object to be safe.
So change your code into:
@Entity
public class EntityA {
private EntityB parent;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
public EntityB getParent() {
return parent;
}
...
}
@MappedSuperclass
public class SuperEntity {
private long itemId;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
public long getItemId() {
return itemId;
}
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3894 次 |
| 最近记录: |