OneToOne mapping not working: EntityA.entityB referencing EntityB not mapped to a single property

OneToOne mapping not working: EntityA.entityB referencing EntityB not mapped to a single property

I have two entities, EntityA and EntityB.
EntityA has a composite primary key on two fields: id and flag.

EntityB also has a composite primary key on two fields: id and flag.

The two entities are linked with a common field / column: entityBKey. (This is a foreign key but not explicitly defined as such at the database level, if that makes a difference. Old design can’t really change much)

This is how I am calling EntityA:

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<EntityA> criteriaQuery = builder.createQuery(EntityA.class);
Root<EntityA> from = criteriaQuery.from(EntityA.class);
criteriaQuery.select(from);

But I get this error on application boot:

EntityA.entityB referencing EntityB not mapped to a single property
	at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:203)
	at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:104)
	at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processEndOfQueue(InFlightMetadataCollectorImpl.java:1750)
	at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processFkSecondPassesInOrder(InFlightMetadataCollectorImpl.java:1694)
	at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1623)
	at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:295)
	at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:86)
	at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:479)
	at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:85)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:709)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:746)

In some places I have read it says that non-primary keys can be referenced by using the referencedColumnName attribute but it is clearly not working.
Any ideas what I can do here? Much appreciated.

EntityA:

@Entity
@Table(name = "EntityA")
@IdClass(KeyClass.class)
public class EntityA implements Serializable {
    @Id
    @Column(name = "id", nullable = false)
    protected Integer id = null;
    @Id
    @Column(name = "flag", nullable = false)
    protected Integer flag = null;
    @Column(name = "EntityAKey", nullable = false)
    private String entityAKey = null;
    @Column(name = "EntityBKey", nullable = false)
    private String entityBKey = null;

    @OneToOne(mappedBy="entityA")
    private EntityB entityB;

    public EntityA() {
        super();
    }
}

EntityB:

@Entity
@Table(name = "EntityB")
@IdClass(KeyClass.class)
public class EntityB implements Serializable {
    @Id
    @Column(name = "id", nullable = false)
    protected Integer id = null;
    @Id
    @Column(name = "flag", nullable = false)
    protected Integer flag = null;

    @Column(name = "EntityBKey", nullable = false)
    private String entityBKey = null;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumns({
            @JoinColumn(name = "entityBKey", referencedColumnName = "entityBKey", insertable = false, updatable = false),
            @JoinColumn(name = "flag", referencedColumnName = "flag", insertable = false, updatable = false)}
    )
    @Where(clause = "flag=1")
    private EntityA entityA;

    public EntityB() {
        super();
    }
}

KeyClass:

public class KeyClass implements Serializable {
    private Integer id = null;
    private Integer flag = null;

    public KeyClass() {
    }

    public KeyClass(Integer id, Integer flag) {
        this.id = id;
        this.flag = flag;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getFlag() {
        return flag;
    }

    public void setFlag(Integer flag) {
        this.flag = flag;
    }

    @Override
    public boolean equals(Object o) {
        ...
    }

    @Override
    public int hashCode() {
        ...
    }
}

Which Hibernate version are you using? Can you please try updating to the latest and report back again if the problem still persists?

We are on 5.6.7.Final. Changed it to 5.6.9.Final, that’s the max we could go to and same result.

In that case, please create a JIRA issue along with a reproducer.