【发布时间】:2012-06-15 12:25:50
【问题描述】:
使用单个表的 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" EntityA 的 ID 为“12345”,EntityB 的 ID 为“12345”。
现在,当我加载 ID 为“12345”的 EntityA 时,在 EntityMapA 类型的 getEntityMaps() 中有一个条目,但该 EntityMapA 上的鉴别器值为“B”。
这里出了什么问题?为什么将带有鉴别器“B”的行映射到 EntityMapA 实体?
是不是因为我在父类上将 EntityId 映射了两次(一次使用 @Column(name="ENTITY_TYPE",insertable=false,updatable=false),然后再次将每个 JoinColumn 映射到实际实体?
更新 顺便说一句,EntityA 集合中列出的 EntityMapA 从未真正创建过。当您尝试加载实体时,您会收到一个异常,告诉您该实体不存在。所以对我来说看起来像是 Hibernate 中的一个错误。
【问题讨论】:
标签: hibernate jakarta-ee jpa