当前位置: 首页 > 知识库问答 >
问题:

JPA:OpenJPA:type指定的id类与该类的主键字段不匹配

柯升
2023-03-14

我包含了一个错误,这是我在构建JPA类到表模式中时遇到的...有人能指导我如何解决这个错误吗。以及当其中一个键实际上是外键时如何生成复合键。我的注释哪里不对?

错误

 org.apache.openjpa.util.MetaDataException: The id class specified by type "class Specialty" does not match the primary key fields of the class. 
Make sure your identity class has the same primary keys as your persistent type, including pk field types. Mismatched property: "personId"

表架构

create table Location(
  id int primary key,
  city varchar(255),
  state varchar(100),
  country varchar(255)
);
create table Person(
  id int primary key,
  name varchar(100)
);
create table Photographer(
  id int primary key references Person(id) on update cascade on delete cascade,
  livesIn int not null references Location(id) on update cascade on delete no action
);
create table Specialty(
  photographer int references Photographer(id) on update cascade on delete cascade,
  type enum('portrait','landscape','sport'),
  primary key(photographer, type)
);
create table Photo(
  id int primary key,
  takenAt timestamp not null,
  takenBy int references Photographer(id) on update cascade on delete no action,
  photographedAt int references Location(id) on update cascade on delete no action,
  type enum('portrait','landscape','sport')
);
create table Appearance(
  shows int references Person(id) on update cascade on delete cascade,
  isShownIn int references Photo(id) on update cascade on delete cascade,
  primary key(shows, isShownIn)
);

person.java

@Entity
public class Person implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String name;


location.java

@Entity
public class Location implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String city;

    private String state;

    private String country;


photographer.java

@Entity
public class Photographer implements Serializable {

    @Id
    @ManyToOne
    @Column(name = "id")
    private Person personId;

    @ManyToOne
    @Column(name = "livesIn")
    private Location livesIn;

photo.java

@Entity
public class Photo implements Serializable {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    // Foreign Key
    @ManyToOne
    @JoinColumn(name = "takenBy")
    private Photographer takenBy;

    // Foreign Key
    @ManyToOne
    @JoinColumn(name = "photographedAt")
    private Location photographedAt;

    @Basic(optional = false)
    @Column(name = "takenAt", insertable = false, updatable = false)
    @Temporal(TemporalType.DATE)
    private Date takenAt;

    @Enumerated(EnumType.STRING)
    private PhotoType type;

照片类型

 
public enum PhotoType {
    PORTRAIT("portrait"), LANDSCAPE("landscape"), SPORT("sport");
    private String type;

    PhotoType(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

}

specialty.java

 
import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;

@Entity
public class Specialty implements Serializable {

    @EmbeddedId
    protected SpecialtyPK specialtyPK;

    public Specialty() {
        super();
    }

    public Specialty(SpecialtyPK specialtyPK) {
        super();
        this.specialtyPK = specialtyPK;
    }

}

@Embeddable
class SpecialtyPK implements Serializable {

    @ManyToOne
    @Column(name = "id")
    private Photographer personId;

    @Enumerated(EnumType.STRING)
    private PhotoType type;

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((personId == null) ? 0 : personId.hashCode());
        result = prime * result + ((type == null) ? 0 : type.hashCode());
        return result;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        SpecialtyPK other = (SpecialtyPK) obj;
        if (personId == null) {
            if (other.personId != null)
                return false;
        } else if (!personId.equals(other.personId))
            return false;
        if (type != other.type)
            return false;
        return true;
    }

    public SpecialtyPK() {
        super();
        // TODO Auto-generated constructor stub
    }

    public SpecialtyPK(Photographer personId, PhotoType type) {
        super();
        this.personId = personId;
        this.type = type;
    }

}

使用复合键尝试也失败并给出相同的错误。

大量的互联网搜索并没有导致任何解决方案。

共有2个答案

葛修筠
2023-03-14

问题是2倍。一个问题是specialtypk中的personId映射。@column用于基本映射;您需要使用@JoinColumn注释指定用于连接的列。

第二个也是更重要的是,主键类不应该包含关系--如果它是可嵌入的,定义为主键类不要紧,它应该只包含基本映射或其他主键(JPA 2.0中允许derrived ID,这意味着可以嵌套键类)。因此您需要一个SpecialtyPK类,该类具有一个类型为'int'的personId。然后,您可以在Specialty中指定ManyToOne映射,并添加@MapSID将其指向int。这样,您只需要设置关系,而不需要管理可嵌入的内的基本映射。

@Entity
public class Specialty implements Serializable {

    @EmbeddedId
    protected SpecialtyPK specialtyPK;

    @MapsId("personId")
    protected Photographer photographer;
..

class SpecialtyPK implements Serializable {

    @Column(name = "id")
    private int personId;//defaults to basic

..

或者你可以删除embeddedId并将摄影师标记为ID。

姬朗
2023-03-14

在我看来,您有一个复合主键,但您通过注释告诉JPA您有一个嵌入式主键。就像我告诉每一个第一次来参加项目的人:

让最简单的事情首先开始工作,而不考虑效率,并根据客户的需要进行优化。

过早的优化是多软件问题的根源。

 类似资料:
  • sp_get_term($term_id) 功能: 返回指定分类 参数: $term_id:分类id 返回: 类型数组,符合条件的分类 示例: <?php $term_id=1; $term=sp_get_term($term_id ); //获取分类信息 print_r($term); //打印出分类信息 ?> 返回数组说明: term_id:分类id name:分类名称 taxono

  • 我有一个像下面这样的模型: 但是当我尝试通过将其中一个访问者与一个联系人交换来更新一个visitRequest,并尝试在一个CRUD存储库visit request repository . save(visit request)上执行该方法时;我得到了这个异常: Servlet。路径为[]的上下文中servlet[dispatcherServlet]的service()引发了异常[Request

  • 我有一个实体类,jpa正在抛出一个验证异常,说明指定了主键。我不明白为什么。 请参阅下面的详细信息:*内部异常:javax.Persistence.persistenceException:Exception[EclipseLink-28018](Eclipse Persistence.Exceptions.EntityManagerSetupException异常描述:Predeployment

  • 我正面临以下问题: “链”来自ViewModelHelper类定义 2) 2.1),->可以用替换 如果我将2.1)应用于1.1)&1.2),我们可以看到,参数T是一致的 从1)遵循从2)遵循,从2.1)遵循可以被替换,如果我正确理解,这个错误应该不会出现,有人能解释一下吗?为什么eclipse会给我这个错误? 谢谢!

  • 定义不可变类的策略表明 所有字段都应该是最终字段。 对于ex: 为什么一定要最终决定? 因为我没有给出setter方法吗?它不能改变。谢谢。