JPA Cast例外

时间:2013-03-18 11:35:20

标签: java database oracle jpa

我正在尝试使用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。

你有什么建议吗?我可能错过了一些东西。 提前感谢所有人!

2 个答案:

答案 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
}