将@OneToOne与2个外键引用一起使用是否安全

时间:2018-07-16 23:29:29

标签: java mysql sql jpa hibernate-mapping

我必须创建一个新表来存储用户已接受的条款和条件的版本号以及他们单击接受时的时间戳。 (该表仅包含与用户有关的信息。有关T&C版本本身的信息存储在另一个表中)

这意味着用户A可以接受3个版本的条款和条件,这些版本已经随着时间的推移进行了更新。我最关心的唯一版本是用户同意的最新版本,但是出于完整性考虑,我仍然需要保留接受版本的历史记录。

场景:

  
      
  1. 在存储版本记录之前,我已经在数据库中有了用户条目。

  2.   
  3. 可能有一些用户不同意任何条款和条件。

  4.   
  5. 1用户可能随着时间的推移接受了多个版本的条款与条件

  6.   
  7. 我想以最小的步骤检索用户已接受的最新版本以及用户对象。

  8.   
  9. 如果可能,当我删除用户时,如果该用户的所有接受版本记录也都被删除(级联删除时的外键),我希望它

  10.   

我该如何实施一个干净的解决方案?我想出了两种可能性,但不确定是否可行。

解决方案1:@OnetoOne与用户保持FK参考与用户已同意的最新T&C记录的单向关系。 T&C记录会将user_id保留为非主要且非唯一的FK字段。

@Entity
@Table(name = “user”)
public class User {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name =“user”)
  Long id;

  @Column(name = “username”)
  private String username;

     .........

  @JoinColumn(name = “terms_record_id”)
  @OneToOne(cascade = CascadeType.ALL)
  private TermsRecord termsRecord;
  // joined on terms_record_id to get only the latest version accepted
}

记录版本用户的实体已接受

@Entity
@Table(name = “terms_record”)
public class TermsRecord {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = “terms_record_id”)
  private Long id;

  @Column(name = “agreed_on”)
  private Date agreedOn;

  @column(name =“version_no”)
  private String versionNo;

  // I’m not sure if it needs to have userId in here as well?
  @column(name = “user_id”)
  private Long userId;

   ........ 
}

在数据库中

create table user {
   user_id bigint as Primary Key,
   ...
   terms_record_id FOREIGN KEY references terms_record(terms_record_id);
   // to refer to the most updated version
}

create table terms_record {
   terms_record_id bigint NOT NULL,
   user_id bigint,
   PRIMARY KEY(terms_record_id),
   FOREIGN KEY(user_id)  REFERENCES User(user_id)            cascade on delete     
   // to keep the records of terms user has agreed to
}

在代码中,它将类似于:

User userA = getUser(user_id);
TermsRecord tr = new TermsRecord();
tr.setVersionNo(“1.0.5”);
tr.setAcceptedOn(....);
userA.setTermsRecord(tr);
save(userA);

因此,如果用户A以前接受过1.0.3版的术语,它将不会从terms_record表中删除该条目,但是当您从数据库中检索到userA时,它将拉出不同的版本号。 例如。

userA.getTermsRecord.getVersionNo == 1.0.5

并且在terms_record表中

  terms_record_id |     version_no
______________________________________
..........        |        .........
    3             |         1.0.3
    5             |         1.0.5
 ........         |        ..........

解决方案2

用户类中的单向@OneToMany批注 外键user_id存储在TermsRecord中,并在删除时级联。然后手动获取最新版本。

0 个答案:

没有答案