我使用单个表在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 =&#34; B&#34;和ENTITY_ID =&#34; 12345&#34; 有一个EntityA,ID为#34; 12345&#34;和具有相同ID的实体B&#34; 12345&#34;。
现在当我使用id&#34; 12345&#34;加载EntityA时在EntityMapA类型的getEntityMaps()中有一个条目,但该EntityMapA上的鉴别器值是&#39; B&#39;。
这里出了什么问题?为什么一行有鉴别器&#39; B&#39;映射到EntityMapA实体?
是因为我在父类上映射EntityId两次(一次是@Column(name =&#34; ENTITY_TYPE&#34;,insertable = false,updatable = false),然后每次JoinColumn再映射到实际实体?
更新 顺便说一句,EntityA上的集合中列出的EntityMapA从未真正创建过。当您尝试加载实体时,您会收到一个异常,告诉您该实体不存在。所以看起来像Hibernate中的一个bug给我。
答案 0 :(得分:2)
问题是您使用相同的列来映射两个不同的关联。 AFAIK,不支持此功能。
这实际上是一件好事,因为使用两个单独的列来引用不同的东西会更清晰。它允许在这些列上定义FK约束,例如,这对于当前解决方案是不可能的,因为该列根据行保存EntityA或EntityB的ID。