Home > OS >  Hibernate unidirectional @OneToMany association triggers updates of foreign keys
Hibernate unidirectional @OneToMany association triggers updates of foreign keys

Time:02-08

I have the following entities:

@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "TYPE")
public class Type implements Serializable {

  private static final long serialVersionUID = 563398089758359222L;

  @NotNull
  @Column(name = "OBJECT_TYPE")
  private String objectType;

  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TypeNameId")
  @SequenceGenerator(name = "TypeNameId", sequenceName = "SQ_TNAME_WL", allocationSize = 1)
  private Long id;

  @NotNull
  @ToString.Include
  private String code;

  @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
  @JoinColumn(name = "BOUND_TO_ID", referencedColumnName = "ID")
  @JoinColumn(name = "BOUND_TO_CLASS", referencedColumnName = "OBJECT_TYPE")
  private Set<Translation> translations;

}


@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "TRANSLATION")
public class Translation implements Serializable {

  private static final long serialVersionUID = -4974947078465122824L;

  @NotNull
  @Column(name = "OBJECT_TYPE")
  private String objectType;

  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TranslationId")
  @SequenceGenerator(name = "TranslationId", sequenceName = "SQ_LTRANSLATION_WL", allocationSize = 1)
  private Long id;

  @Size(max = 4000)
  @Column(name = "VALUE")
  private String value;

  @Size(max = 150)
  @Column(name = "LOCALE")
  private String locale;


  @Size(max = 150)
  @Column(name = "BOUND_TO_CLASS")
  private String boundToClass;

  @Column(name = "BOUND_TO_ID")
  private Long boundToId;

}

Other entities may also have their translations in Translations table but do not include mappings with respect to Translation entity. When creating a Type with translations, Hibernate wants to do the SQL below:

Hibernate: insert into type (code, object_type, id) values ("code","Type", 1)

Hibernate: insert into translation (bound_to_class, bound_to_id, locale, object_type, value, id) values (null, null, "en_US", "Translation", "American code", 2)

There is a non-deferrable unique constraint on the columns bound_to_id, bound_to_class and locale. It is not possible to create translations in the same locale for different types since bound_to_class and bound_to_id are null in Hibernate SQL.

How do I change the mappings to allow translation creations without making the unique constraint deferrable or using bidirectional association?

CodePudding user response:

Other than setting up a bi-directional relationship:

public class Type {
  ..
  @OneToMany(mappedBy="type", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
  private Set<Translation> translations;
}
..
public class Translation {
  ..
  @ManyToOne
  @JoinColumn(name = "BOUND_TO_ID", referencedColumnName = "ID")
  @JoinColumn(name = "BOUND_TO_CLASS", referencedColumnName = "OBJECT_TYPE")
  Type type;
}

Which would then setup the fk values for you, the alternative is to map the BOUND_TO_ID and BOUND_TO_CLASS within the Translation yourself, and pull them yourself from any Type instances:

public class Translation {
  ..
  @Column(name = "BOUND_TO_CLASS")
  private String objectType;

  @Column(name = "BOUND_TO_ID")
  private Long objectId;

}

You'd then need to mark the relationship within Type as read-only:

public class Type {
  ..
  @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
  @JoinColumn(name = "BOUND_TO_ID", referencedColumnName = "ID", updatable=false, insertable=false)
  @JoinColumn(name = "BOUND_TO_CLASS", referencedColumnName = "OBJECT_TYPE", updatable=false, insertable=false)
  private Set<Translation> translations;
}

Since the Type id is generated, you'd need to call persist on Type first, flush the context to make sure the ID is assigned, and then use the ID and objectType to set any Transaction instances you wished to create to point to it.

  •  Tags:  
  • Related