Spring JPA/Hibernate复合主外键多通映射

Spring JPA/Hibernate复合主外键多通映射,spring,hibernate,jpa,orm,spring-data-jpa,Spring,Hibernate,Jpa,Orm,Spring Data Jpa,***已解决-更新决议*** 我有两张桌子: 通知-由UserId+NotificationDetail组成的复合键 通知\u详细信息-单个主键 我想使用JPA来持久化和读取这些对象,但无法使manytone映射正常工作 多个通知映射到一个通知详细信息 表: create table notification( notification_user_id int not null, notification_detail_id int

***已解决-更新决议***

我有两张桌子:

通知-由UserId+NotificationDetail组成的复合键

通知\u详细信息-单个主键

我想使用JPA来持久化和读取这些对象,但无法使manytone映射正常工作

多个通知映射到一个通知详细信息

表:

create table notification(
notification_user_id        int             not null,
notification_detail_id     int              not null,
notification_status_cd      int             not null,
primary key(notification_user_id, notification_detail_id),
constraint pkey_notification_detail foreign key(notification_detail_id) references notification_detail(notification_detail_id),
constraint pkey_notification_status_cd foreign key(notification_status_cd) references lk_notification_status(notification_status_id)
);

create table notification_detail (
notification_detail_id  int             auto_increment,
notification_type_cd    int             not null,
notification_message    varchar(50)     not null,
primary key(notification_detail_id),
constraint pkey_notification_type_cd foreign key(notification_type_cd) references lk_notification_type(notification_type_id)
);
***已解决并更正JPA设置:***

***此错误现已解决***:

***原始问题:***

我尝试过各种不同的配置。我能想到的最好办法是,我的情况很复杂,因为父对象“notification”有一个复合键“notification\u detail\u id”,它也是子对象的主键。这使得Hibernate很难先持久化子级,然后获取密钥并将其保存给父级


我意识到我的注释在某个地方不正确,但就是想不出来。

看起来你在处理一个“派生身份”。将您的类更改为如下所示:

class NotificationId implements Serializable {
    private static final long serialVersionUID = 1L;
    Integer notifiedUserId;
    Integer details;
    ...
}


@Entity
@IdClass(NotificationId.class)
@Table(name="notification")
public class Notification implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @NotNull
    @Column(name="notification_user_id")
    private Integer notifiedUserId;

    @Id
    @NotNull
    @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
    @JoinColumn(name="notification_detail_id")
    private NotificationDetail details;

    @NotNull
    @Column(name="notification_status_cd")
    private Integer statusCd;

    @Column(name="update_timestamp")
    private Date timestamp;

    ...
}
注意:

  • NotificationId.notificationDetailId
    已重命名为
    details
    ,以匹配
    Notification
  • 通知。notificationDetailId
    已被删除
  • 通知。详细信息已标记为
    @Id
您的字段模型似乎暗示您应该对
通知
用户
之间的关系做同样的事情


JPA 2.1规范第2.4.1节讨论了派生标识。

看起来您正在处理“派生标识”。将您的类更改为如下所示:

class NotificationId implements Serializable {
    private static final long serialVersionUID = 1L;
    Integer notifiedUserId;
    Integer details;
    ...
}


@Entity
@IdClass(NotificationId.class)
@Table(name="notification")
public class Notification implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @NotNull
    @Column(name="notification_user_id")
    private Integer notifiedUserId;

    @Id
    @NotNull
    @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
    @JoinColumn(name="notification_detail_id")
    private NotificationDetail details;

    @NotNull
    @Column(name="notification_status_cd")
    private Integer statusCd;

    @Column(name="update_timestamp")
    private Date timestamp;

    ...
}
注意:

  • NotificationId.notificationDetailId
    已重命名为
    details
    ,以匹配
    Notification
  • 通知。notificationDetailId
    已被删除
  • 通知。详细信息已标记为
    @Id
您的字段模型似乎暗示您应该对
通知
用户
之间的关系做同样的事情


JPA 2.1规范第2.4.1节讨论了派生身份。

这正是我的问题!感谢您识别并提供100%准确的解决方案!这正是我的问题!感谢您识别并提供100%准确的解决方案!
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'notificati0_.details_notificationDetailId' in 'field list'
class NotificationId implements Serializable {
    private static final long serialVersionUID = 1L;
    Integer notifiedUserId;
    Integer details;
    ...
}


@Entity
@IdClass(NotificationId.class)
@Table(name="notification")
public class Notification implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @NotNull
    @Column(name="notification_user_id")
    private Integer notifiedUserId;

    @Id
    @NotNull
    @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
    @JoinColumn(name="notification_detail_id")
    private NotificationDetail details;

    @NotNull
    @Column(name="notification_status_cd")
    private Integer statusCd;

    @Column(name="update_timestamp")
    private Date timestamp;

    ...
}