OnyToMany:发生SQLException:未知列' xxx'在'字段列表'

时间:2016-01-28 03:41:36

标签: java mysql spring hibernate jpa

我想为我的JPA实例使用单向关系(Hibernate 4.3.10) RegionalCountry - > RegionalArea1 - > RegionalArea2

@Entity
public class RegionalCountry {
    @Id
    @Column(unique = true, nullable = false, updatable = false, length = 36)
    private String uuid = UUID.randomUUID().toString();
    private String countryName;
    private String countryCode;

    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
    private List<RegionalArea1> regionalArea1;
    ...//getters&setters
}

@Entity
public class RegionalArea1 {    
    @Id
    @Column(unique = true, nullable = false, updatable = false, length = 36)
    private String uuid = UUID.randomUUID().toString();
    private String area1Name;   
    private String area1Code;   

    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
    private List<RegionalArea2> regionalArea2;
    ...//getters&setters
}

@Entity
public class RegionalArea2 {            
    @Id
    @Column(unique = true, nullable = false, updatable = false, length = 36)
    private String uuid = UUID.randomUUID().toString();
    private String area2Name;   
    private String area2Code;
    ...//getters&setters
}

然后我想使用Spring JpaRepository按国家/地区代码获取国家/地区及其区域实例:

public interface RegionalCountryRepository extends JpaRepository<RegionalCountry, UUID> {   
    public RegionalCountry findOneByCountryCode(String countryCode);
}

当我打电话

regionalCountryRepository.findOneByCountryCode(countryCode);

发生SQLException:Unknown column 'regionalar0_.regional_country' in 'field list'

同样的例外是regionalCountryRepository.findAll();

有没有办法在区域实例之间使用单向关系而不会出现此错误?

令人惊讶的是,嵌入式数据库的单元测试对上面的代码运行良好,但是当我们处理真正的MySQL数据库时,会发生异常。

@Test
public void testFindByCountryCode() {

    southernArea = new RegionalArea1();
    southernArea.setArea1Code("00");
    southernArea.setArea1Name("SOUTHERN");

    chejuDoArea = new RegionalArea1();      
    chejuDoArea.setArea1Code("00");
    chejuDoArea.setArea1Name("CHEJU-DO");

    korea = new RegionalCountry();
    korea.setCountryName("Korea, Republic of");
    korea.setCountryCode("KOR");
    korea.setRegionalArea1s(Arrays.asList(southernArea, chejuDoArea));

    repository.save(korea);     
    RegionalCountry countryFetched = repository.findOneByCountryCode("KOR");
    Assert.assertNotNull(countryFetched);
}

更新:架构如下

CREATE TABLE REGIONAL_AREA2(
    UUID VARCHAR(36) NOT NULL,    
    AREA2CODE VARCHAR(255),
    AREA2NAME VARCHAR(255)
);

CREATE TABLE REGIONAL_AREA1(
    UUID VARCHAR(36) NOT NULL,    
    AREA1CODE VARCHAR(255),
    AREA1NAME VARCHAR(255)
);

CREATE TABLE REGIONAL_AREA1_REGIONAL_AREA2(
    REGIONAL_AREA1_UUID VARCHAR(36) NOT NULL,
    REGIONAL_AREA2_UUID VARCHAR(36) NOT NULL
);  


CREATE TABLE REGIONAL_COUNTRY(
    UUID VARCHAR(36) NOT NULL,  
    COUNTRY_CODE VARCHAR(255),
    COUNTRY_NAME VARCHAR(255)
);        

CREATE TABLE REGIONAL_COUNTRY_REGIONAL_AREA1(
    REGIONAL_COUNTRY_UUID VARCHAR(36) NOT NULL,
    REGIONAL_AREA1_UUID VARCHAR(36) NOT NULL
);

3 个答案:

答案 0 :(得分:0)

可能有以下几个原因:

  1. 我没有看到您的类变量到表字段regional_country的任何映射。请确保使用注释@Column指定变量映射到的正确表字段。例如,如果变量countryCode映射到表字段country_code,则应该注释如下:@Column(name = "country_code") private int countryCode;
  2. 对于变量private String countryName; private String countryCode;,如果它们在数据库模式中有映射字段,请使用@Column对其进行注释
  3. 如果您提供有关您的问题的更多信息,将会很有帮助:例如,您的数据库架构。

答案 1 :(得分:0)

我尝试使用Hibernate Session重现您的问题而不使用任何JpaRepository。我必须将所有集合关联的映射从List更改为Set导致“无法同时获取多个行李”错误

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Set<RegionalArea1> regionalArea1;

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Set<RegionalArea2> regionalArea2;

一切正常,没有任何错误。可能是,它也会对你有所帮助。如果它没有帮助:

Hibernate认为REGIONAL_COUNTRY_REGIONAL_AREA1联接表包含regional_country列,但此表包含REGIONAL_COUNTRY_UUID。因此,尝试通过@JoinTable注释指定连接列名称,或重新创建数据库模式,或者更改命名策略(如果指定)。

Hibernate为国家/地区代码搜索生成的SQL

 select
        this_.f_uuid as f_uuid1_3_2_,
        this_.f_country_code as f_countr2_3_2_,
        this_.f_country_name as f_countr3_3_2_,
        regionalar2_.fk_regional_country as fk_regio1_4_4_,
        regionalar3_.f_uuid as fk_regio2_4_4_,
        regionalar3_.f_uuid as f_uuid1_0_0_,
        regionalar3_.f_area1code as f_area2_0_0_,
        regionalar3_.f_area1name as f_area3_0_0_,
        regionalar4_.fk_regional_area1 as fk_regio1_1_5_,
        regionalar5_.f_uuid as fk_regio2_1_5_,
        regionalar5_.f_uuid as f_uuid1_2_1_,
        regionalar5_.f_area2code as f_area2_2_1_,
        regionalar5_.f_area2name as f_area3_2_1_ 
    from
        spring_regional_countries this_ 
    left outer join
        spring_regional_countries_regional_area1s regionalar2_ 
            on this_.f_uuid=regionalar2_.fk_regional_country 
    left outer join
        spring_regional_area1s regionalar3_ 
            on regionalar2_.fk_regional_area1=regionalar3_.f_uuid 
    left outer join
        spring_regional_area1s_regional_area2s regionalar4_ 
            on regionalar3_.f_uuid=regionalar4_.fk_regional_area1 
    left outer join
        spring_regional_area2s regionalar5_ 
            on regionalar4_.fk_regional_area2=regionalar5_.f_uuid 
    where
        this_.f_country_code=?

答案 2 :(得分:0)

感谢所有答案,但问题出在REGIONAL_COUNTRY_REGIONAL_AREA1表列名称中。列名末尾的Postfix _UUID 会混淆MySQL。 可以修复此问题重命名中间数据表的列

DROP TABLE IF EXISTS REGIONAL_AREA1_REGIONAL_AREA2;
DROP TABLE IF EXISTS REGIONAL_AREA1_REGIONAL_AREA2;

CREATE TABLE REGIONAL_AREA1_REGIONAL_AREA2(
    REGIONAL_AREA1 VARCHAR(36) NOT NULL,
    REGIONAL_AREA2 VARCHAR(36) NOT NULL
);  

CREATE TABLE REGIONAL_COUNTRY_REGIONAL_AREA1(
    REGIONAL_COUNTRY VARCHAR(36) NOT NULL,
    REGIONAL_AREA1 VARCHAR(36) NOT NULL
);