I try to create a @OneToOne relationship with an entity whose id is composed of 2 properties and where one of them is fixed by a discriminator annotation.
@Entity
@Table(name = "LIBELLE")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorOptions(force = true, insert = false)
public class Libelle {
private LibelleId id;
public Libelle() {
}
@EmbeddedId
public LibelleId getId() {
return id;
}
public void setId(final LibelleId id) {
this.id = id;
}
@Embeddable
public static class LibelleId implements Serializable {
private String code;
private String type;
public LibelleId(String code, String type) {
this.code = code;
this.type = type;
}
public LibelleId() {
}
@Column(length = LIBELLE_CODE_MAX_SIZE)
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Column(length = LIBELLE_TYPE_MAX_SIZE)
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
LibelleId libelleId = (LibelleId) o;
return Objects.equals(code, libelleId.code) &&
Objects.equals(type, libelleId.type);
}
@Override
public int hashCode() {
return Objects.hash(code, type);
}
}
}
@Entity
@DiscriminatorValue("A")
public class LibelleA extends Libelle {
}
@Entity
@Table(name = "Test")
public class Test implements Serializable {
private LibelleA libelleA;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "code_value", referencedColumnName = "code")
public LibelleA getLibelleA () {
return libelleA;
}
public void setLibelleA(final LibelleA libelleA) {
this.libelleA = libelleA;
}
}
With this configuration the @OneToOne fails with the exception : AnnotationException: referencedColumnNames(code) of Test.libelleA referencing LibelleA not mapped to a single property.
It looks like the discrimator value is ignored on the relation and to make it work I need to specify it manually replacing the @JoinColumn with a formula :
@JoinColumnsOrFormulas({
@JoinColumnOrFormula(column = @JoinColumn(name = "code_value", referencedColumnName = "code")),
@JoinColumnOrFormula(formula = @JoinFormula(value = "'A'", referencedColumnName = "type"))
})
The problem of using such formula is that it prevent me from using Envers to track this field changes.
So I was wondering if you knew a better configuration to make this relation work without a formula.