Ids and Complex Data Mapping over REST & Hibernate

2019-08-11 08:24发布

问题:

I have some pretty complex data objects which relate to each other, that I need to have live in two separate databases (two applications). The storage of the data is not a worry, and both of the applications (source and target) are looking at the same base class of data to handle setters, getters, hibernate, etc.

Since I want to design a REST service to be very item centric, I have a few calls that setup the objects in bulk. After those are loaded in, I was thinking of going through and calling an item specific REST call to GET information based on the item's ID. This brings up a few issues I am not sure if REST can handle.

If the ID on the source application is set, I am worried about item associations based on ID in Hibernate @JoinTable when it ports over through a REST call to the target. Trying to use the ID from target to GET item/{id}/relationships yields issues since the {id} is from the target and doesn't match source after data has been loaded.

Is there a way in REST or Hibernate to handle moving large sets of complex custom relational data from a source to a target system using REST calls, ID based URLs, without collisions or issues?

Example Classes and DB (code simplified a lot to ignore some complexity):

@Table(name="GUIDELINE")
public class Guideline{
  private String name;
  private Set<RelatedItem> relatedItems;
  protected Long id;
  /** Database id of this object used by Hibernate. */
  @Id
  @GeneratedValue(generator="increment")
  @GenericGenerator(name="increment", strategy = "increment")
  @XmlElement
  @Column(name = "ID", unique = true, nullable = false)
  public Long getId() {
    return id;
  }

  @ManyToMany(fetch = FetchType.EAGER)
  @JsonIgnore
  @JoinTable(name = "RELATIONSHIPS", 
  joinColumns = { @JoinColumn(name = "GUIDELINE_ID", referencedColumnName = "ID", table = "GUIDELINE", nullable = false) }, 
  inverseJoinColumns = { @JoinColumn(name = "ITEM_ID", referencedColumnName = "ID", table = "RELATEDITEM", nullable = false) })
  public Set<RelatedItem> getRelatedItems() {
    return relatedItems;
  }

  @Column(name = "NAME", unique = true, nullable = false, length = 240)
  public String getName(){
    return this.name;
  }
}

@Table(name="RELATEDITEM")
public class RelatedItem{
  private String name;
  protected Long id;
  /** Database id of this object used by Hibernate. */
  @Id
  @GeneratedValue(generator="increment")
  @GenericGenerator(name="increment", strategy = "increment")
  @XmlElement
  @Column(name = "ID", unique = true, nullable = false)
  public Long getId() {
    return id;
  }

  @Column(name = "NAME", unique = true, nullable = false, length = 240)
  public String getName(){
    return this.name;
  }
}

回答1:

General approach is to use natural key to identify objects in distributed environment. You can add natural key in addition to generated key or use generator to create UUID values for primary keys.