我正在尝试使用Oracle和JPA构建数据库模式。我是JPA的新手,我总是直接使用sql。 我需要创建的是两个表:第一个包含当前的VOIP调用,另一个包含这些调用的历史记录。这两个表是相同的。 在JPA中我写了这个:
@Entity
@Table(name = "voip_currentCalls")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class VoipCurrentCall implements Serializable {
private static final long serialVersionUID = 1L;
protected CompositeID id;
protected Timestamp startTime;
protected Timestamp endTime;
protected String calledNumber;
protected String callingNumber;
protected Person contact;
protected CallSource source;
protected CallStatus status;
protected CallType type;
protected CallStage stage;
@Entity
@Table(name = "voip_historyCalls")
public class VoipHistoryCall extends VoipCurrentCall implements Serializable {
...
正如您所看到的那样,第二个表没有其他字段,但它只是简单地扩展了第一个表。 当我尝试将VoipCurrentCall转换为VoipHistoryCall时,我获得了java.lang.ClassCastException:VoipCurrentCall无法转换为VoipHistoryCall。
你有什么建议吗?我可能错过了一些东西。 提前感谢所有人!
答案 0 :(得分:4)
这就是Java的设计方式;你不能只能以相反的方式将超类强制转换为子类。它与JPA没有任何关系。
答案 1 :(得分:2)
好吧,如果您尝试投射的对象是 而不是 历史记录调用,则演员阵容肯定会失败。 JPA实体仍然与常规Java对象绑定相同的转换规则。一个很好的例子:
Object obj = new Object();
String str = (String) obj;
上面将在运行时产生一个类转换异常,如果一个String是一个Object,如果Object不是一个String则无关紧要。就你的JPA设计而言,你实际应该稍微有所不同。 JPA提供了一些定义继承层次结构的标准方法。在您的情况下,我建议使用@MappedSuperclass
。像这样:
@MappedSuperclass
public abstract class BaseVoipCurrentCall implements Serializable {
@Id
private CompositeID id;
private Timestamp startTime;
private Timestamp endTime;
private String calledNumber;
private String callingNumber;
private Person contact;
private CallSource source;
private CallStatus status;
private CallType type;
private CallStage stage;
// Constructors, getters/setters
}
@Entity
@Table(name = "voip_currentCalls")
public class VoipCurrentCall extends BaseVoipCurrentCall {
// Voip current call specific attributes and logic
}
@Entity
@Table(name = "voip_historyCalls")
public class VoipHistoryCall extends BaseVoipCurrentCall {
// Voip history call specific attributes and logic
}