简体   繁体   中英

Hibernate - One to one relation single table inheritance

I have 3 entities BaseFoo , FooAbc , FooAbcDetail . FooAbc extends base entity BaseFoo . I'm trying to do one to one relation between FooAbc and FooAbcDetail .

@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "foo")
@Audited
@AuditOverride(forClass = Auditable.class)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type_id", discriminatorType = DiscriminatorType.INTEGER)
public abstract class BaseFoo extends Auditable implements Serializable {

    @Id
    @Column(name = "id")
    private Long id;

    //other fields
}

@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Audited
@AuditOverride(forClass = BaseFoo.class)
@DiscriminatorValue("2")
public class FooAbc extends BaseFoo implements Serializable {

    @EqualsAndHashCode.Exclude
    @ToString.Exclude
    @NotAudited
    @OneToOne(mappedBy = "fooAbc",
              fetch = FetchType.LAZY,
              cascade = CascadeType.ALL,
              orphanRemoval = true,
              optional = false)
    private FooAbcDetail fooAbcDetail;

    //other fields
}

@Data
@Entity
@Table(name = "foo_abc_detail")
public class FooAbcDetail implements Serializable {

    @Id
    @Column(name = "foo_id"/* foo_abc_id (I tried both) */)
    private Long id;

    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    @MapsId //also tried @MapsId("id")
    @OneToOne(fetch = FetchType.LAZY)
    private FooAbc fooAbc; //also tried BaseFoo

    //other fields
}

While project starting up Hibernate throws:

org.hibernate.MappingException: Unable to find column with logical name: id in org.hibernate.mapping.Table(public.foo_abc_detail) and its related supertables and secondary tables

What is the problem here?

Environment

  • Hibernate 5.3.10.Final
  • Spring Boot 2.1.7.RELEASE

This error is telling you that there is no column on the foo_abc_detail table called foo_id .The column on foo_abc_detail is just called id .

@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "foo")
@Audited
@AuditOverride(forClass = Auditable.class)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type_id", discriminatorType = DiscriminatorType.INTEGER)
public abstract class BaseFoo extends Auditable implements Serializable {

    @Id
    @Column(name = "id")
    private Long id;

    //other fields
}

@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Audited
@AuditOverride(forClass = BaseFoo.class)
@DiscriminatorValue("2")
public class FooAbc extends BaseFoo implements Serializable {

    @EqualsAndHashCode.Exclude
    @ToString.Exclude
    @NotAudited
    @OneToOne(mappedBy = "fooAbc",
              fetch = FetchType.LAZY,
              cascade = CascadeType.ALL,
              orphanRemoval = true,
              optional = false)
    private FooAbcDetail fooAbcDetail;

    //other fields
}

@Data
@Entity
@Table(name = "foo_abc_detail")
public class FooAbcDetail implements Serializable {

    @Id
    @Column(name = "id")
    private Long id;

    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    @MapsId //also tried @MapsId("id")
    @OneToOne(fetch = FetchType.LAZY)
    private FooAbc fooAbc; //also tried BaseFoo

    //other fields
}

Okey I solved. I don't know if this is the best way to do it but it works! I replaced the @MapsId annotation via @JoinColumn . Final result of the FooAbcDetail class like as below.

@Data
@Entity
@Table(name = "foo_abc_detail")
public class FooAbcDetail implements Serializable {

    @Id
    @Column(name = "id")
    private Long id;

    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id", referencedColumnName = "id", nullable = false)
    private FooAbc fooAbc;

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM