使用单个表的 JPA 类层次结构有一个奇怪的行为。基本上我有两个实体 EntityMapA 和 EntityMapB,它们都扩展了 EntityMap。鉴别器值为“ENTITY_TYPE”,EntityMapA 为 A,EntityMapB 为 B。不知何故,我得到了 EntityMapA 类型的对象,其中鉴别器值设置为“B”!
我使用 Hibernate 3.3 作为 JPA 提供程序。
这是代码:
@Entity
@Table(name="ENTITY_MAP")
@DiscriminatorColumn(name = "ENTITY_TYPE")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class EntityMap implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Long entityMapId;
//This is a ID of another entity we map to. It is a different entity type depending on
//The subclass. For EntityMapA it would map to EntityA and for EntityMapB it would map
// to EntityB
private Long entityId;
private String discriminator;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "ENTITY_MAP_ID", unique = true, nullable = false)
public Long getEntityMapId() {
return entityMapId;
}
public void setEntityMapId(Long EntityMapId) {
this.entityMapId = entityMapId;
}
@Column(name="ENTITY_TYPE",insertable=false,updatable=false)
public String getDiscriminator() {
return discriminator;
}
public void setDiscriminator(String discriminator) {
this.discriminator = discriminator;
}
@Column(name="ENTITY_ID",insertable=false,updatable=false)
public Long getEntityId() {
return entityId;
}
public void setEntityId(Long entityId) {
this.entityId = entityId;
}
//there are other common fields in here which are left out
}
@Entity
@DiscriminatorValue("A")
public class EntityMapA extends EntityMap {
/**
*
*/
private static final long serialVersionUID = -8709307036005000705L;
private EntityA entityA;
public static final String DISCRIMINATOR = "A";
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ENTITY_ID", nullable = false)
@NotNull
public EntityA getEntityA() {
return entityA;
}
public void setEntityA(EntityA entityA) {
this.entityA = entityA;
}
}
@Entity
@DiscriminatorValue("B")
public class EntityMapB extends EntityMap {
/**
*
*/
private static final long serialVersionUID = -8709307036005000705L;
public static final String DISCRIMINATOR = "B";
private EntityB entityB;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ENTITY_ID", nullable = false)
@NotNull
public EntityB getEntityB() {
return entityB;
}
public void setEntityB(EntityB entityB) {
this.entityB = entityB;
}
}
最后我在EntityA中有一个映射:
@OneToMany(cascade=CascadeType.ALL,fetch = FetchType.LAZY, mappedBy = "entityA")
public List<EntityMapA> getEntityMaps() {
return entityMaps;
}
public void setEntityMaps(List<EntityMapA> entityMaps) {
this.entityMaps = entityMaps;
}
现在我有一个 ENTITY_MAP 行,其中 ENTITY_TYPE = "B" 和 ENTITY_ID = "12345" 有一个 ID 为 "12345" 的 EntityA 和一个 ID 为 "12345" 的 EntityB。
现在,当我加载 ID 为“12345”的 EntityA 时,在 EntityMapA 类型的 getEntityMaps() 中有一个条目,但该 EntityMapA 上的鉴别器值为“B”。
这里出了什么问题?为什么带有鉴别器“B”的行映射到 EntityMapA 实体?
是因为我在父类上将 EntityId 映射两次(一次使用 @Column(name="ENTITY_TYPE",insertable=false,updatable=false),然后再将每个 JoinColumn 映射到实际实体?
更新 顺便说一句,EntityA 集合中列出的 EntityMapA 从未真正创建。当您尝试加载实体时,您会收到一个异常,告诉您该实体不存在。所以对我来说看起来像是 Hibernate 中的一个错误。