与非主键一对一的 JPA 给出 Unable to find column with logical name 错误

JPA one to one with non primary key gives Unable to find column with logical name error

我正在用 springboot + jpa + hibernate 设计货币对的实体 table。数据库是postgres。 Schema如下-

币种DDL

CREATE TABLE currency (
    id bigint NOT NULL PRIMARY KEY,
    entity_id VARCHAR(255) NOT NULL UNIQUE,
    code VARCHAR(255),
    name VARCHAR(255),
    description VARCHAR(255),
    denomination_code VARCHAR(255),
    denomination_name VARCHAR(255),
    denomination_description VARCHAR(255),
    denomination_units integer,
    status VARCHAR(255)
);

currency_pair

的 DDL
CREATE TABLE currency_pair (
    id bigint NOT NULL PRIMARY KEY,
    entity_id VARCHAR(255) NOT NULL UNIQUE,
    code VARCHAR(50) NOT NULL,
    name VARCHAR(250) NOT NULL,
    description VARCHAR(500) NOT NULL,
    base_currency_id VARCHAR(255) NOT NULL REFERENCES currency(entity_id),
    quote_currency_id VARCHAR(255) NOT NULL REFERENCES currency(entity_id),
    status VARCHAR(255),
);

和我的实体类如下:-

货币实体-

@Entity
@Table(name = "currency")
public class Currency implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NaturalId
    @Column(nullable = false)
    private String entityId;

    @Column(nullable = false)
    private String code;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String description;

    @Column(nullable = false)
    private String denominationCode;

    @Column(nullable = false)
    private String denominationName;

    @Column(nullable = false)
    private String denominationDescription;

    @Column(nullable = false)
    private Integer denominationUnits;

    @Column(nullable = false)
    private String mask;

    @Column(nullable = false)
    private String status;

    /* getters and setters */
}

货币对实体 -

@Entity
@Table(name = "currency_pair")
public class CurrencyPair implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NaturalId
    @Column(nullable = false)
    private String entityId;

    @Column(nullable = false)
    private String code;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String description;

    @OneToOne
    @JoinColumn(name = "base_currency_id", referencedColumnName = "entity_id")
    private Currency baseCurrency;

    @OneToOne
    @JoinColumn(name = "quote_currency_id", referencedColumnName = "entity_id")
    private Currency quoteCurrency;

    @Column(nullable = false)
    private String status;

    /* Getters and setters */
}

base_currency_id and quote_currency_id in currency_pair table 引用非主键列 entity_id in currency tables .

当我启动我的 springboot 应用程序时,出现以下错误 -

Caused by: org.hibernate.MappingException: Unable to find column with logical name: entity_id in org.hibernate.mapping.Table(currency) and its related supertables and secondary tables at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:832) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final] at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:256) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final] at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:101) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final] at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processEndOfQueue(InFlightMetadataCollectorImpl.java:1827) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final] at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processFkSecondPassesInOrder(InFlightMetadataCollectorImpl.java:1771) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final] at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1658) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final] at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:287) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:904) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:935) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final] at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.1.8.RELEASE.jar:5.1.8.RELEASE] ... 95 common frames omitted

注意:我无法更改 ddl 查询,所以我该如何修复实体 类

找不到列 entity_id,因为它在 Currency table 中定义为 entityId

您可以通过将 name 属性添加到 Currency 上的 entityId 列来修复它 class :

@Entity
@Table(name = "currency")
public class Currency implements Serializable {

    // ...

    @NaturalId
    @Column(name="entity_id", nullable = false)
    private String entityId;

    // ...

因为您在 CurrencyPair 中有 referencedColumnName = "entity_id",它与 Currency 有关系。 在 Currency 中,名称是 entityId,与 entity_id 不匹配。 您可以添加 name 属性 ,如下所示 Currency

改变

@NaturalId
@Column(nullable = false)
private String entityId;

@NaturalId
@Column(name = "entity_id", nullable = false)
private String entityId;