我们使用Wildfly 8.2,因此使用JEE 7,其功能为JPA 2.1 Loadgraphs。
假设我们有以下分层实体结构(缩写类):
@Entity
public class IsEntity {
@Id private Long id;
@ManyToOne(fetch = FetchType.LAZY)
private IsEntity parentIsEntity;
@OneToOne(fetch = FetchType.LAZY)
@JoinTable(name = "IS_SHOULD", joinColumns = { @JoinColumn(name = "IS_ID") },
inverseJoinColumns = { @JoinColumn(name = "SHOULD_ID", unique = true) }, foreignKey = @ForeignKey(
name = "FK_SHOULD_ID"),
inverseForeignKey = @ForeignKey(name = "FK_IS_SHOULD"))
private ShouldEntity shouldEntity;
}
@Entity
@NamedEntityGraph(name = "withShouldParent", attributeNodes = { @NamedAttributeNode("parentShouldEntity") }),
public class ShouldEntity {
@Id private Long id;
@Column
private String someProperty;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PARENT_ID", foreignKey = @ForeignKey(name = "FK_SHOULD_PARENT"))
private ShouldEntity parentShouldEntity;
@OneToOne(mappedBy = "shouldEntity", fetch = FetchType.LAZY)
@JoinTable(name = "IS_SHOULD", joinColumns = { @JoinColumn(name = "SHOULD_ID") },
inverseJoinColumns = { @JoinColumn(name = "IS_ID", unique = true) }, foreignKey = @ForeignKey(
name = "FK_IS_SHOULD"),
inverseForeignKey = @ForeignKey(name = "FK_SHOULD_IS"))
private IsEntity isEntity;
}
这种结构背后的功能要求是,我们首先在"应该" -side建模层次结构,然后创建相应的"是"在这个过程中。
鉴于,我有以下实体:
IsEntity(id = 10, shouldEntityId = 20, parentIsEntity = null)
ShouldEntity(id = 20, isEntityId = 10, parentShouldEntity = null, someProperty = "firstShouldParent")
ShouldEntity(id = 21, isEntityId = null, parentShouldEntity = 20, someProperty = "firstShouldChild")
现在我执行以下两个查询:
entityManager.find(IsEntity.class, 10); // IsEntityQuery
EntityGraph loadGraph = entityManager.getEntityGraph("withShouldParent");
Map<String, Object> queryHints = new HashMap<>();
queryHints.put( "javax.persistence.loadgraph", loadGraph );
ShouldEntity loadedEntity = entityManager().find( ShouldEntity.class, 21, queryHints ) );
以下对查询对象的调用崩溃:
loadedEntity.getParentShouldEntity().getSomeProperty();
错误消息是:
java.lang.ClassCastException: de.somecompany.ShouldEntity _ $$ _ jvst757_14无法转换为 de.somecompany.ShouldEntity
如果我省略IsEntityQuery
,则ShouldEntity
及其父级已正确加载!因此看起来,如果加载图应该加载实体管理器已经看到的实体,那么第一级缓存(?)和JPA加载图似乎存在问题。恕我直言,实体经理应该足够聪明地意识到ShouldEntity(id=20)
在查询IsEntity
时只是懒得加载,并且必须按照加载图的描述急切地获取它。至少这是我从规范第3.7.4.2节中读到的内容:
如果属性是一对一或多对一关系,并且 属性在属性节点中指定,即默认提取 获取目标实体的图表
所以,我的问题基本上是:预期的行为,甚至可能在某处描述,它是Hibernate 4.3.7中的错误(与WildFly 8.2.0一起提供)还是JPA规范中缺少的一部分?< / p>
非常感谢任何澄清!