0

I have a couple of tables with relation as in the image below

enter image description here

I created hibernate data model as follows

@Entity
@Table(name = "SUBJECT")
public class Subject {

  @Column(name = "NAME")
  private String name;

  @Column(name = "ADDRESS")
  private String address;

  @Column(name = "CLIENT_ID")
  private String clientId;

  @OneToMany(mappedBy = "subject", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
  private List<SSI> SSIs;

  // getters and setters
  ...
  
}
@Entity
@Table(name = "SUBJECT_IDENTIFIER")
public class SubjectIdentifier {

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


  @Column(name = "AUTHORITY")
  private String authority;


  @Column(name = "TYPE")
  private String type;


  @ManyToOne
  @JoinColumns({
      @JoinColumn(name = "SUBJECT_ID", referencedColumnName = "ID", insertable = true,
          updatable = true,
      @JoinColumn(name = "CLIENT_ID", referencedColumnName = "CLIENT_ID", insertable =
          true, updatable = true)
  })
  private Subject subject;

  // getters and setters
  ...
}
@Entity
@Table(name = "SSI")
public class SSI {
  @ManyToOne
  @JoinColumns({
      @JoinColumn(name = "SUBJECT_ID", referencedColumnName = "ID", insertable = true,
          updatable = true),
      @JoinColumn(name = "CLIENT_ID", referencedColumnName = "CLIENT_ID", insertable =
          true, updatable = true)
  })
  private Subject subject;

  @OneToOne(cascade = CascadeType.ALL)
  @JoinColumns({
      @JoinColumn(name = "SUBJECT_IDENTIFIER_ID", referencedColumnName = "ID", insertable = true,
          updatable = true),
      @JoinColumn(name = "CLIENT_ID", referencedColumnName = "CLIENT_ID", insertable =
          true, updatable = true)
  })
  private SubjectIdentifier subjectIdentifier;

  // getters and setters
  ...
}

I intend to create the entities as follows

  ...
  Subject s = new Subject();
  //.. initialization of s goes here

  SubjectIdentifier si = new SubjectIdentifier();
  //.. initialization of si goes here

  SSI ssi = new SSI();
  ssi.setSubject(s);
  ssi.setSubjectIdentifier(si);

  s.setSSI(ssi);

  ...
  emProvider.get().persist(s); 

When I run this, I get following error

org.hibernate.MappingException: Repeated column in mapping for entity: *.SSI column: CLIENT_ID (should be mapped with insert="false" update="false")

If I set insert="false" update="false" for CLIENT_ID, it would error again about mixing of insert & update with other column in the @Joincolumns

If I set insert="false" update="false" for all the @JoinColumns then it will not persist the objects.

How to really handle this kind of entity creation?

techBeginner
  • 3,792
  • 11
  • 43
  • 59

1 Answers1

1

That's not so easy. If you want that, you have to introduce another attribute for storing the client id and maintain this denormalization:

@Entity
@Table(name = "SSI")
public class SSI {

  @Column(name = "CLIENT_ID")
  private String clientId;

  @Column(name = "SUBJECT_ID")
  private String subjectId;

  @Column(name = "SUBJECT_IDENTIFIER_ID")
  private String subjectIdentifierId;

  @ManyToOne
  @JoinColumns({
      @JoinColumn(name = "SUBJECT_ID", referencedColumnName = "ID", insertable = false,
          updatable = false),
      @JoinColumn(name = "CLIENT_ID", referencedColumnName = "CLIENT_ID", insertable =
          false, updatable = false)
  })
  private Subject subject;

  @OneToOne(cascade = CascadeType.ALL)
  @JoinColumns({
      @JoinColumn(name = "SUBJECT_IDENTIFIER_ID", referencedColumnName = "ID", insertable = false,
          updatable = false),
      @JoinColumn(name = "CLIENT_ID", referencedColumnName = "CLIENT_ID", insertable =
          false, updatable = false)
  })
  private SubjectIdentifier subjectIdentifier;

  // getters and setters
  ...
}
Christian Beikov
  • 15,141
  • 2
  • 32
  • 58
  • I get this error `org.hibernate.AnnotationException: Mixing insertable and non insertable columns in a property is not allowed` – techBeginner Aug 29 '22 at 08:23
  • Well, in that case you will have to model the two columns as separate fields as well and mark the join columns all as `insertable = false, updatable = false`. I updated my answer. – Christian Beikov Aug 29 '22 at 08:27
  • Then it wouldn't insert object into SUBJECT_IDENTIFIER table when I'm creating new subject as there are no id yet. – techBeginner Aug 29 '22 at 08:51
  • You will either have to handle the insert manually then, by calling `EntityManager#persist` before, or you simply use a second `CLIENT_ID` column. Another alternative could be to use `@JoinColumnOrFormula({@JoinColumn(...), @JoinFormula("CLIENT_ID")})`, which essentially allows you to "mix" `insertable`/`updatable` with `true`/`false` implicitly. – Christian Beikov Aug 29 '22 at 10:11
  • Thats throwing exception `ClassCastException: class org.hibernate.mapping.Formula cannot be cast to class org.hibernate.mapping.Column (org.hibernate.mapping.Formula and org.hibernate.mapping.Column are in unnamed module of loader org.eclipse.jetty.webapp.WebAppClassLoader` – techBeginner Aug 29 '22 at 10:19
  • If that is really throwing an error on startup, please create an issue in the issue tracker(https://hibernate.atlassian.net) with a test case(https://github.com/hibernate/hibernate-test-case-templates/blob/master/orm/hibernate-orm-5/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java) that reproduces the issue. – Christian Beikov Aug 29 '22 at 11:34