JPQL 只返回第一条记录

JPQL only returning the first record

Spring Boot/JPA/Hibernate/MySQL 这里。我有下表:

describe states;
+------------+---------------------+------+-----+---------+----------------+
| Field      | Type                | Null | Key | Default | Extra          |
+------------+---------------------+------+-----+---------+----------------+
| state_id   | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| country_id | bigint(20) unsigned | NO   | MUL | NULL    |                |
| state_name | varchar(250)        | NO   |     | NULL    |                |
| state_code | varchar(3)          | YES  | MUL | NULL    |                |
+------------+---------------------+------+-----+---------+----------------+

describe countries;
+--------------+---------------------+------+-----+---------+----------------+
| Field        | Type                | Null | Key | Default | Extra          |
+--------------+---------------------+------+-----+---------+----------------+
| country_id   | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| country_name | varchar(250)        | NO   | UNI | NULL    |                |
| country_code | varchar(3)          | NO   | UNI | NULL    |                |
+--------------+---------------------+------+-----+---------+----------------+

当我 运行 SELECT * FROM states WHERE country_id = 1; 我得到:

+----------+------------+----------------------+------------+
| state_id | country_id | state_name           | state_code |
+----------+------------+----------------------+------------+
|     3805 |          1 | Alabama              | NULL       |
|     3806 |          1 | Alaska               | NULL       |
|     3807 |          1 | Arizona              | NULL       |
|     3808 |          1 | Arkansas             | NULL       |
|     3810 |          1 | California           | NULL       |
...
|     3860 |          1 | Virginia             | NULL       |
|     3861 |          1 | Washington           | NULL       |
|     3862 |          1 | West Virginia        | NULL       |
|     3863 |          1 | Wisconsin            | NULL       |
|     3864 |          1 | Wyoming              | NULL       |
+----------+------------+----------------------+------------+

(All 50 states)

有对应的JPA实体:

@Entity
@Table(name = "states")
public class State {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @JsonIgnore
    @NotNull
    private String name;

    @Column(name = "state_code")
    @NotEmpty
    private String code;

    @ManyToOne(fetch = FetchType.EAGER, cascade = [CascadeType.PERSIST, CascadeType.MERGE])
    @JoinColumn(name = "country_id", referencedColumnName = "country_id")
    @NotNull
    @Valid
    private Country country;

    // Getters, setters & constructors
}

@Entity
@Table(name = "countries")
public class Country {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @JsonIgnore
    @NotNull
    private String name;

    @Column(name = "state_code")
    @NotEmpty
    private String code;

    // Getters, setters & constructors
}

我还有以下CrudRepository:

public interface StateRepository extends CrudRepository<State, Long> {
    @Query("FROM Province WHERE country = :country")
    public Set<Province> findAllByCountry(@Param("country") Country country);
}

最后我有一个服务方法,它接受一个 Country 和 returns 所有与之关联的 States:

public Set<Province> getProvincesByCountryCode(Country country) {
    log.info("Country id is " + country.getId());
    Set<Province> provinces = stateRepository.findAllByCountry(country);
    log.info("Found " + provinces.size() + " states associated with this country (" + country.getCode() + ")");

    // TODO: Return 'provinces' once I get this fixed...
    return null;
}

当这个服务方法执行时,它只有returns一个List<State>,里面只有一个State(所以大小是1),日志输出是:

Country id is 1
Found 1 states associated with this country (US)

所以 MySQL 数据库知道所有 50 个州,但 StateRepository 只返回 1。特别是它返回第一个州记录(阿拉巴马州),我觉得这很有趣......

很明显 CrudRepository 中我的 JPQL 出了点问题,谁能发现遗漏了什么?

使用以下代码:

public interface StateRepository extends JpaRepository<Province, Long> {
    public Set<Province> findAllByCountry(Country country);
}

此外,调试此类内容的最佳方法是在您的应用中启用 sql 日志,查看 sql 生成的日志,您可以轻松弄清楚看到的[=11]背后发生了什么=]

最后我只进行了本地查询:

String query = "SELECT * FROM states where country_id = " + countryId;
entityManager.createNativeQuery(query, State.class).getResultList();

很有魅力!