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
并返回与之关联的所有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;
}
当此服务方法执行时,它只返回一个List<State>
,其中包含一个State
(因此大小为1),日志输出为:
Country id is 1
Found 1 states associated with this country (US)
所以MySQL数据库知道所有50个状态,但StateRepository
只返回1.特别是它返回第一个状态记录(阿拉巴马州),我觉得这很有意思......
显然CrudRepository
中我的JPQL出了问题,有人能发现缺少的内容吗?
答案 0 :(得分:0)
使用以下代码:
public interface StateRepository extends JpaRepository<Province, Long> {
public Set<Province> findAllByCountry(Country country);
}
另外调试这种东西的最好方法是在你的应用程序中启用sql日志,看看sql生成的日志,你可以轻松搞清楚看到后面的东西是什么
答案 1 :(得分:0)
最后我选择了原生查询:
String query = "SELECT * FROM states where country_id = " + countryId;
entityManager.createNativeQuery(query, State.class).getResultList();
像魅力一样!