gpt4 book ai didi

java - Hibernate中复合ID如何映射Key类

转载 作者:行者123 更新时间:2023-11-30 06:43:55 28 4
gpt4 key购买 nike

如何实现复合键,让我们做一个非常简单的例子,用户参加 Activity ,三个数据库表:User、Event、Users_Attending_Events 最后一个表有三列:userID、eventID;它们与其他两个表各自的 ID 和 success 相连接,确定用户是否向事件展示。

我希望参加是一个单独的类,并且不要直接加入用户和事件,因为参加包含“成功”信息,并且必须单独管理。

我的实现

用户对象:

@Entity
@Table(name = "[users]")
public class User implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer userID;
@JsonIgnore
@OneToMany(mappedBy = "attend", targetEntity = Attending.class, fetch = FetchType.LAZY)
private Set<Attending> attendEvents = new HashSet<Attending>();
...
// setters, getters, constructors, equal and hash ...
}

事件:

@Entity
@Table(name = "events")
public class Event implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer eventID;
@JsonIgnore
@OneToMany(mappedBy = "attend", targetEntity = Attending.class, fetch = FetchType.LAZY)
private Set<Attending> participants = new HashSet<Attending>();
...
// setters, getters, constructors, equal and hash ...
}

参加类(class):

@Entity
@Table(name = "users_attending_events")
public class Attending implements Serializable {

@EmbeddedId
protected AttendingID attend;

private Integer success;
...
// setters, getters, constructors, equal and hash ...
}

AttendingID 类,用于复合键:

  @Embeddable
public class AttendingID implements Serializable {

@ManyToOne(targetEntity = User.class, fetch = FetchType.LAZY)
@JoinColumn(name = "users_userID", referencedColumnName = "userID")
private Integer user;

@ManyToOne(targetEntity = Event.class, fetch = FetchType.LAZY)
@JoinColumn(name = "events_eventID", referencedColumnName = "eventID")
private Integer event;
...
// setters, getters, constructors, equal and hash ...
}

运行时出现异常:

org.hibernate.MappingException: Foreign key (FKlerh9fv4q1rjiusg0ful3m15j:users_attending_events [events_eventID,users_userID])) must have same number of columns as the referenced primary key (users [userID])

我错过了什么?

最佳答案

问题:

异常非常简单,说明映射的外键不是预期的类型,而您的问题是您试图在 Integer 类型的属性中映射 @ManyToOne 关系 这是错误的部分。

解决方案:

@ManyToOne 注释应引用您案例中 UserEvent 的映射 Entity,而不是基元实体的类型或主键。

但是要定义Embeddable主键,您有两个选择:

  1. 仅使用映射实体主键作为 Embeddable 类中的属性。

您的代码将是:

@Embeddable
public class AttendingID implements Serializable {

@Column(name = "users_userID")
private Integer userID;

@Column(name = "events_eventID")
private Integer eventID;

...
// setters, getters, constructors, equal and hash ...
}
  • 或者使用两个映射实体作为可嵌入主键中的属性,并通过 @ManyToOne 注释引用它们。
  • 因此,在您的代码中,您只需要更改 user

    的类型
    @Embeddable
    public class AttendingID implements Serializable {

    @ManyToOne(targetEntity = User.class, fetch = FetchType.LAZY)
    @JoinColumn(name = "users_userID", referencedColumnName = "userID")
    private User user;

    @ManyToOne(targetEntity = Event.class, fetch = FetchType.LAZY)
    @JoinColumn(name = "events_eventID", referencedColumnName = "eventID")
    private Event event;

    ...
    // setters, getters, constructors, equal and hash ...
    }

    文档:

    要进一步阅读和更多选项,您可以查看 5.1.2.1. Composite identifier Section in Hibernate Mapping Documentation它清楚地显示并解释了映射复合主键的所有可能情况。

    <小时/>

    编辑:

    重新阅读你的问题,更好地关注问题并从 vue 的设计角度思考它之后,我认为用 ManyToMany 可以更好地说明你的情况 a ManyToMany UserEvent 实体之间的关系,其中连接表 Attending 具有额外列 success,它将更好地处理您的情况并解决问题。

    我建议你看看这个Hibernate Many-to-Many Association with Extra Columns in Join Table Example tutorial它显示了类似的ManyToMany 解决方案。

    关于java - Hibernate中复合ID如何映射Key类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43977517/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com