实体类未指定主键

5

我有一个实体类,继承了四级继承关系,其中最高级别的父类定义了主键(@Id),但我遇到了问题,出现了以下错误:

实体类[class D]未指定主键。它应该定义@Id、@EmbeddedId或@IdClass之一。如果您已经使用这些注解中的任何一个定义了PK,请确保您的实体类层次结构中没有混合访问类型(既有字段又有属性被注释)。

这是我的继承体系:

A->B->C->(实体)D

这是我的非实体类,它为它的子类提供值:

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

@MappedSuperclass
public class A implements Serializable {
@Id
@GeneratedValue
protected Long id;
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
protected Date deleted;

 public Date getDeleted() {
    return deleted;
 }

 public void setDeleted(Date deleted) {
    this.deleted = deleted;
 }

 public Long getId() {
    return id;
 }

 public void setId(Long id) {
    this.id = id;
 }
}

这是它的一个子元素:

@MappedSuperclass
public abstract class B extends A implements Serializable {

}

B->C

import javax.persistence.Entity;
import javax.persistence.Transient;


@MappedSuperclass
public class C extends B{

protected String name;
protected String description;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}
}

最后是C->(实体)D

@Entity
public class D extends C{
private String codeD;

public String getCodeD(){return codeD;}
public String setCodeD(String codeD) {this.codeD = codeD;}
}

根据我找到的每个来源,通常使用@MappedSuperclass并实现Serializable应该可以解决问题。虽然我已经尝试了在层次结构的每一步实现Serializable,但是我收到了相同的错误消息。
我目前正在使用Payara 4.1.1.1621。我不知道这可能是问题所在,因为我在某些线程中看到过这种Payara错误,但它们都神奇地自己解决了。

实体没问题。你的JPA提供程序似乎有问题,它是哪一个? - Neil Stockton
1
您发布的映射看起来没问题,事实上我尝试在一个简单的应用程序中复制它,并且它可以在Payara Server 162中正常工作。您是否使用任何ORM XML映射文件?它可能包含额外的映射导致问题吗? - OndroMih
我的JPA提供程序是EclipseLink,EclipseLink的javax.persistence版本为2.1.0。我没有使用任何ORM XML映射文件。 - Antoine de Villers
更新:我尝试使用 EclipseLink JPA 的 2.1.1 版本进行更新,但仍然收到相同的错误消息。 - Antoine de Villers
@OndroMih 谢谢您的建议。您的建议解决了我的问题。由于复制粘贴问题,我在ORM.xml中有一个不正确的映射。 - Mr. Port St Joe
2个回答

3

我通过将我的基类添加到persistence.xml文件中解决了这个错误。


1
配置似乎符合规范要求。
我能想到的唯一可以添加的是@Column注释,以明确声明数据库列名称:
@Id
@GeneratedValue
@Column(name = "id")
protected Long id;
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
@Column(name = "deleted")
protected Date deleted;

尝试一下。如果仍然无法正常工作,请尝试注释所有标记为@MappedSuperClass的类中的字段。

另外,C类的字段应标记为protected而不是private?


谢谢您的回答,但是它没有奏效。C类现在将其字段标记为protected而不是private。谢谢。 - Antoine de Villers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接