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

标签 java spring hibernate jpa hibernate-mapping

如何实现复合键,让我们做一个非常简单的例子,用户参加 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/

    相关文章:

    java - repaint() 在 Swing 中不起作用

    spring - 如何处理pom.xml中的 "omitted for conflict with.."消息?

    java - Spring Security addFilterAfter 未注册过滤器

    hibernate - 使用计数从 hibernate 实体获取行并加入

    java - 虽然我在服务器中启用了 Java,但我面临着 java 路径问题

    java - Flink 在 timeWindow 上应用函数

    java - 我的 Java 应用程序是否必须具有 x86 和 x64 版本?

    java - 基于 Action 的验证最佳实践 Spring MVC

    java - 如何跟踪每个用户查看的项目

    java - 类似于 HQL 中的 % 运算符