使用JPA生成的SQL语句不正确

时间:2015-11-30 14:02:05

标签: java jpa

在我描述我的确切问题之前,我将向您展示相关代码。我有一个由两个实体( PaymentProvider 国家)组成的数据库和一个实现多对多关系的连接表。

CREATE TABLE paymentprovider (
    name VARCHAR(255) NOT NULL,
    displayName VARCHAR(255) NOT NULL,
    PRIMARY KEY(name)
);

CREATE TABLE country (
    code VARCHAR(255) NOT NULL,
    name VARCHAR(255) NOT NULL,
    PRIMARY KEY(code)
);

CREATE TABLE providercountry (
    paymentprovider_name VARCHAR(255) NOT NULL,
    country_code VARCHAR(255) NOT NULL,
    FOREIGN KEY(paymentprovider_name) REFERENCES paymentprovider(name),
    FOREIGN KEY(country_code) REFERENCES country(code)
);

Java-Implementation看起来像这样(使用JPA):

国家

@Entity
@Table(name = "country")
@NamedQueries({
    @NamedQuery(name = Country.GET_ALL,
            query ="SELECT c FROM Country c")
})
public class Country implements Serializable {
    private static final long serialVersionUID = 0L;

    private String code;
    private String name;
    private List<PaymentProvider> paymentProviders = new ArrayList<>();

    private static final String PREFIX = "foo.bar";
    public static final String GET_ALL = PREFIX + ".get_all";

    public Country(){
    }

    @Id
    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @ManyToMany(fetch = FetchType.EAGER, targetEntity=PaymentProvider.class)
    @JoinTable(name = "providercountry", joinColumns = {@JoinColumn(name = "country_code", referencedColumnName = "code")}, inverseJoinColumns = {
            @JoinColumn(name = "paymentprovider_name", referencedColumnName = "name")})
    public List<PaymentProvider> getPaymentProviders() {
        return paymentProviders;
    }

    public void addPaymentProviders(PaymentProvider paymentProvider) {
        this.paymentProviders.add(paymentProvider);
    }

    public void setPaymentProviders(List<PaymentProvider> paymentProviders) {
        this.paymentProviders = paymentProviders;
    }

PaymentProvider:

@Entity
@Table(name = "paymentprovider")
public class PaymentProvider implements Serializable {

    private static final long serialVersionUID = 1L;


    private String name;
    private String displayname;
    private List<Country> countries = new ArrayList<>();

    public PaymentProvider(){
    }

    @ManyToMany(mappedBy = "paymentProviders")
    public List<Country> getCountries() {
        return countries;
    }

    public void addCountry(Country country) {
        this.countries.add(country);
    }

    public void setCountries(List<Country> countries) {
        this.countries = countries;
    }

    public String getCode() {
        return displayname;
    }

    public void setCode(String code) {
        this.displayname = code;
    }

    @Id
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

而我所要做的就是像这样执行SQL语句:

public List<Country> getAll() {
    TypedQuery<Country> query = entityManager.createNamedQuery(Country.GET_ALL, Country.class);
    return query.getResultList();
}

这让我有一个错误:

引起:org.h2.jdbc.JdbcSQLException:找不到列“PAYMENTPRO1_.CODE”;

所以我继续看看生成的SQL:

select  paymentpro0_.country_code as country_1_0_0_, 
        paymentpro0_.paymentprovider_name as paymentp2_2_0_, 
        paymentpro1_.name as name1_1_1_, 
        paymentpro1_.code as code2_1_1_ 
from    providercountry paymentpro0_ inner join paymentprovider paymentpro1_ 
        on paymentpro0_.paymentprovider_name=paymentpro1_.name 
        where paymentpro0_.country_code=?

在我看来, - 不知何故 - 国家和PaymentProvider引起了混淆,因为,正如生成的SQL语句所示,有一个与paymentprovider-table而不是country-table的连接。知道我有什么困惑吗?

1 个答案:

答案 0 :(得分:2)

您对PaymentProvider中的Country关系进行了热切的提取。您发布的查询是该国家的支付提供商的热切提取。

它失败了,因为您的付款服务提供商上没有代码列,但您的PaymentProvider实体方法中有一个代码列。它是基于不在私有displayName变量上的方法映射您的实体。