2016-05-21 22 views
0

は*** 解決解像度/ wを更新しました* **JPA/Hibernateは複合主キーForiegn ManyToOneマッピング

私は2つのテーブルを持っていますユーザーID + NotificationDetail

notification_detail -

単一の主キー

JPAを使用してこれらのオブジェクトを永続化して読み込みたいが、ManyToOneマッピングを動作させることができない。

多くの通知にマップ通知_詳細

テーブル:

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セットアップ:* **

class NotificationId implements Serializable { 
    private static final long serialVersionUID = 1L; 
    Integer notificationUserId; 
    Integer details; 
    public Integer getNotificationUserId() { 
     return notificationUserId; 
    } 
    public void setNotificationUserId(Integer notificationUserId) { 
     this.notificationUserId = notificationUserId; 
    } 
    public Integer getDetails() { 
     return details; 
    } 
    public void setDetails(Integer details) { 
     this.details = details; 
    } 
    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((details == null) ? 0 : details.hashCode()); 
     result = prime * result + ((notificationUserId == null) ? 0 : notificationUserId.hashCode()); 
     return result; 
    } 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     NotificationId other = (NotificationId) obj; 
     if (details == null) { 
      if (other.details != null) 
       return false; 
     } else if (!details.equals(other.details)) 
      return false; 
     if (notificationUserId == null) { 
      if (other.notificationUserId != null) 
       return false; 
     } else if (!notificationUserId.equals(other.notificationUserId)) 
      return false; 
     return true; 
    } 
} 

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

    private static final long serialVersionUID = 1L; 

    @Id 
    @NotNull 
    private Integer notificationUserId; 

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

    @NotNull 
    private Integer notificationStatusCd; 

    @NotNull 
    private Integer updateUserId; 

    public Integer getNotificationUserId() { 
     return notificationUserId; 
    } 

    public void setNotificationUserId(Integer notificationUserId) { 
     this.notificationUserId = notificationUserId; 
    } 

    public NotificationDetail getDetails() { 
     return details; 
    } 

    public void setDetails(NotificationDetail details) { 
     this.details = details; 
    } 

    public Integer getNotificationStatusCd() { 
     return notificationStatusCd; 
    } 

    public void setNotificationStatusCd(Integer notificationStatusCd) { 
     this.notificationStatusCd = notificationStatusCd; 
    } 

    public Integer getUpdateUserId() { 
     return updateUserId; 
    } 

    public void setUpdateUserId(Integer updateUserId) { 
     this.updateUserId = updateUserId; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((details == null) ? 0 : details.hashCode()); 
     result = prime * result + ((notificationStatusCd == null) ? 0 : notificationStatusCd.hashCode()); 
     result = prime * result + ((notificationUserId == null) ? 0 : notificationUserId.hashCode()); 
     result = prime * result + ((updateUserId == null) ? 0 : updateUserId.hashCode()); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Notification other = (Notification) obj; 
     if (details == null) { 
      if (other.details != null) 
       return false; 
     } else if (!details.equals(other.details)) 
      return false; 
     if (notificationStatusCd == null) { 
      if (other.notificationStatusCd != null) 
       return false; 
     } else if (!notificationStatusCd.equals(other.notificationStatusCd)) 
      return false; 
     if (notificationUserId == null) { 
      if (other.notificationUserId != null) 
       return false; 
     } else if (!notificationUserId.equals(other.notificationUserId)) 
      return false; 
     if (updateUserId == null) { 
      if (other.updateUserId != null) 
       return false; 
     } else if (!updateUserId.equals(other.updateUserId)) 
      return false; 
     return true; 
    } 

} 

@Entity 
@Table(name="notification_detail") 
public class NotificationDetail implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Integer notificationDetailId; 

    @NotNull 
    private Integer notificationTypeCd; 

    @NotNull 
    private String notificationMessage; 

    @OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL, mappedBy="details") 
    private Set<Notification> notifications; 

    @NotNull 
    private Integer updateUserId; 

    public Integer getNotificationDetailId() { 
     return notificationDetailId; 
    } 

    public void setNotificationDetailId(Integer notificationDetailId) { 
     this.notificationDetailId = notificationDetailId; 
    } 

    public Integer getNotificationTypeCd() { 
     return notificationTypeCd; 
    } 

    public void setNotificationTypeCd(Integer notificationTypeCd) { 
     this.notificationTypeCd = notificationTypeCd; 
    } 

    public String getNotificationMessage() { 
     return notificationMessage; 
    } 

    public void setNotificationMessage(String notificationMessage) { 
     this.notificationMessage = notificationMessage; 
    } 

    public Set<Notification> getNotifications() { 
     return notifications; 
    } 

    public void setNotifications(Set<Notification> notifications) { 
     this.notifications = notifications; 
    } 

    public void addNotification(Notification notification){ 
     if(notifications == null) 
      notifications = new HashSet<Notification>(); 
     notifications.add(notification); 
    } 

    public Integer getUpdateUserId() { 
     return updateUserId; 
    } 

    public void setUpdateUserId(Integer updateUserId) { 
     this.updateUserId = updateUserId; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((notificationDetailId == null) ? 0 : notificationDetailId.hashCode()); 
     result = prime * result + ((notificationMessage == null) ? 0 : notificationMessage.hashCode()); 
     result = prime * result + ((notificationTypeCd == null) ? 0 : notificationTypeCd.hashCode()); 
     result = prime * result + ((notifications == null) ? 0 : notifications.hashCode()); 
     result = prime * result + ((updateUserId == null) ? 0 : updateUserId.hashCode()); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     NotificationDetail other = (NotificationDetail) obj; 
     if (notificationDetailId == null) { 
      if (other.notificationDetailId != null) 
       return false; 
     } else if (!notificationDetailId.equals(other.notificationDetailId)) 
      return false; 
     if (notificationMessage == null) { 
      if (other.notificationMessage != null) 
       return false; 
     } else if (!notificationMessage.equals(other.notificationMessage)) 
      return false; 
     if (notificationTypeCd == null) { 
      if (other.notificationTypeCd != null) 
       return false; 
     } else if (!notificationTypeCd.equals(other.notificationTypeCd)) 
      return false; 
     if (notifications == null) { 
      if (other.notifications != null) 
       return false; 
     } else if (!notifications.equals(other.notifications)) 
      return false; 
     if (updateUserId == null) { 
      if (other.updateUserId != null) 
       return false; 
     } else if (!updateUserId.equals(other.updateUserId)) 
      return false; 
     return true; 
    } 

} 

JPAの使用法:

NotificationDetail details = new NotificationDetail(); 
details.setMessage("Hello"); 
details.setTypeCd(NotificationTypeEnum.INFO); 
detail.setUpdateUserId(userId); 

Notification notif = new Notification(); 
notif.setNotifiedUserId(userId); 
notif.setStatusCd(NotificationStatusEnum.UNREAD); 
notif.setDetails(details); 

notificationRepository.save(notif); 

*** このエラーが解決されました * **:

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'notificati0_.details_notificationDetailId' in 'field list' 

*** オリジナル問題: * **私は異なる構成のすべての種類を試してみた

。親オブジェクト "通知"には、子の主キーである複合キー "notification_detail_id"があるため、私の状況は複雑です。これは、Hibernateが最初に子を永続させ、次にキーを取得して親のために保存することを非常に困難にします。

私の注釈はどこか間違っていることがわかりますが、それを理解できません。

答えて

2

「派生アイデンティティー」を扱っているようです。このように見て、あなたのクラスを変更します。

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; 

    ... 
} 

NB:

  • NotificationId.notificationDetailIdNotification
  • Notification.notificationDetailIdに対応するフィールドに一致するようにdetailsに変更されましたが
  • Notification.detailsを削除されているとマークされていますとして@Id

フィールドモデルは、NotificationUserの関係で同じことを行う必要があることを暗示しているようです。

派生したアイデンティティについては、JPA 2.1仕様、セクション2.4.1で説明します。

+0

これはまさに私の問題でした。それを特定し、100%正確なソリューションを提供していただきありがとうございます! – szxnyc

関連する問題