1

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;
  }
}
Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Walls
  • 3,972
  • 6
  • 37
  • 52
  • As I understand you can not use `id` as a key in distributed environment because different key generators give you different keys. So you should use some natural key or add key that is unique between several instances. Typically, UUID is used for this purpose. Can you add UUID as a @NaturalId for the replicated entities? – svaor Aug 10 '15 at 19:01
  • @svaor UUID would probably work. I'll take a look into that with `@NaturalId` – Walls Aug 10 '15 at 19:11
  • I think UUID can be used as @Id too. But you will need a migration of existed data on production instances... – svaor Aug 10 '15 at 21:07
  • Could you use natural data as your id? – Bohemian Aug 10 '15 at 23:28

1 Answers1

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.

svaor
  • 2,205
  • 2
  • 19
  • 41
  • So after moving the items over they come across with the UUID but on trying to save it I get an error similar to [this post](http://stackoverflow.com/questions/3853106/org-hibernate-stalestateexception-batch-update-returned-unexpected-row-count-fr). The suggestion is to null out the ID, but if I do this, doesn't it remove the use of the UUID being shared between two systems? Thoughts? – Walls Aug 11 '15 at 20:25
  • Do you use UUID as id? I use UUID as a natural id in my project because of some reasons on the database side. But approach with id can be used too. Plz see [this question](http://stackoverflow.com/q/2108178/835000). – svaor Aug 11 '15 at 20:36