Home > Net >  How to join entity using non-primary composite key?
How to join entity using non-primary composite key?

Time:09-24

I have a legacy db where I want to join an entity using a non-primary composite key.

The table definitions:

create table product
(
    id                                  bigint            not null
        primary key,
    accounting_area_id                  varchar(255)      not null,
    domain_object_id                    varchar(255)      not null,
    tenant_id                           varchar(255)      not null,
    display_name                        varchar(255)      not null,
    kind                           varchar(255)      not null,
    constraint product_un
        unique (tenant_id, accounting_area_id, domain_object_id),
    foreign key (kind, tenant_id) references kind (domain_object_id, tenant_id)
);

create table kind
(
    id                                  bigint            not null
        primary key,
    domain_object_id                    varchar(255)      not null,
    tenant_id                           varchar(255)      not null,
    display_name                        varchar(255)      not null,
    constraint kind_un
        unique (tenant_id, domain_object_id)
);

As you can see Product references Kind by foreign key (kind, tenant_id) references kind (domain_object_id, tenant_id).

The entity definitions (some details ommited for brevity):

@Entity
@Table(name = "product")
public class ProductEntity {
    @Id
    @GeneratedValue
    private long id;
    @NaturalId
    @Embedded
    @AttributeOverrides({@AttributeOverride(name = "domain_object_id", column = @Column(name = "domain_object_id")),
            @AttributeOverride(name = "accounting_area_id",
                    column = @Column(name = "accounting_area_id")),
            @AttributeOverride(name = "tenant_id", column = @Column(name = "tenant_id"))

    })
    private AccountingAreaEntityDomainObjectTuple domainObjectTuple;
    @Column(name = "display_name")
    private String displayName;

    @ManyToOne
    @JoinColumns(value = {
            @JoinColumn(name = "wine_kind", referencedColumnName = "domain_object_id", insertable = false, updatable = false),
            @JoinColumn(name = "tenant_id", referencedColumnName = "tenant_id", insertable = false, updatable = false)
    }, foreignKey = @ForeignKey(name = "product_kind_tenant_id_fkey"))
    private KindEntity kind;
}

@Entity
@Table(name = "kind")
public class KindEntity {
    @Id
    @GeneratedValue
    private long id;
    @NaturalId
    @Embedded
    @AttributeOverrides({ @AttributeOverride (name = "domain_object_id", column = @Column (name = "domain_object_id")),
            @AttributeOverride(name = "tenant_id", column = @Column(name = "tenant_id"))
    })
    private TenantEntityDomainObjectTuple domainObjectTuple;
    @Column(name = "display_name", nullable = false)
    private String displayName;
}

@Embeddable
@MappedSuperclass
public class TenantEntityDomainObjectTuple
{
    @Column(name = "domain_object_id", nullable = false)
    private String domainObjectId;
    @Column (name = "tenant_id", nullable = false)
    private String tenantId;
}

@Embeddable
public class AccountingAreaEntityDomainObjectTuple extends TenantEntityDomainObjectTuple
{
  @Column (name = "accounting_area_id", nullable = false)
  private String accountingAreaId;
}

However, this throws the following exception:

org.hibernate.AnnotationException: referencedColumnNames(domain_object_id, tenant_id) of ProductEntity.kind referencing KindEntity not mapped to a single property
    at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:333)
...

Is it even possible to join an entity using a non-primary composite key?

CodePudding user response:

It's possible through hbm.xml, but the annotation model does not support this yet. You can track https://hibernate.atlassian.net/browse/HHH-15355 which is about adding support for this to the annotation model.

  • Related