Bopsi
Bopsi

Reputation: 2436

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

I am designing entity of currency pair table with springboot + jpa + hibernate. Database is postgres. Schema is as follows -

DDL of currency

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)
);

DDL of currency_pair

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),
);

And my entity classes are as follows:-

Currency Entity-

@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 */
}

Currency Pair entity -

@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 refers to non primary key column entity_id in currency tables.

When I am starting my springboot app it gives following error -

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

note: I cannot change the ddl queries, so what can I do to fix the entity classes

Upvotes: 0

Views: 691

Answers (2)

Romil Patel
Romil Patel

Reputation: 13747

As you have referencedColumnName = "entity_id" in CurrencyPair which has a relation with Currency. In Currency, the name is entityId which doesn't match with entity_id. You can add name attribute as follow in Currency

Change

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

To

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

Upvotes: 1

Hülya
Hülya

Reputation: 3433

Can not find column entity_id because it is defined in Currency table as entityId

You can fix it by adding name attribure to entityId column on Currency class :

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

    // ...

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

    // ...

Upvotes: 1

Related Questions