我正在使用Spring Boot 2.3.0以及Spring Data JPA和Spring MVC。我有以下2个实体:
Country.java
@Entity
@Table(name = "countries")
public class Country
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "country_id")
private Integer id;
@Column(name = "country_name" , nullable = false , length = 50)
@NotNull @Size(max = 50)
private String name;
@Column(name = "country_acronym" , length = 3)
@Size(max = 3)
private String acronym;
//Getters-Setters
//Equals-Hashcode (determines equality based only on name attribute)
}
City.java
@Entity
@Table(name = "cities")
public class City
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "city_name")
@Size(max = 50)
private String name;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "city_country")
private Country country;
//Getters-Setters
//Equals/Hashcode (all attributes)
}
我要实现的目标是通过REST调用来节省城市。有一个问题是,我希望在请求的正文中仅提供国家名称,如果该国家存在于国家表中,则它必须能够自行查找引用,否则应首先插入一个新国家然后匹配参考。
作为完整参考,让我提供存储库和控制器类:
CityRepository.java
@Repository
public interface CityRepository extends JpaRepository<City,Integer>
{
}
MainController.java
@RestController
public class MainController
{
@Autowired
private CityRepository cityRepository;
@PostMapping(value = "/countries")
private void insertCountry(@RequestBody @Valid Country country)
{
countryRepository.save(country);
}
@PostMapping(value = "/cities")
public void insertCities(@RequestBody @Valid City city)
{
cityRepository.save(city);
}
}
请求的示例正文:
{
"name": "Nikaia",
"country": {
"name": "Greece"
}
}
我得到的错误是Hibernate总是试图保存该国家,但从不看它是否存在(我遇到了违反约束的情况)。我猜想这个国家永远不会被Hibernate代理,因为它还不是一个持久的实体。有什么方法可以使用Data JPA轻松解决吗?还是我应该降低等级并使用EntityManager?完整的代码示例将不胜感激。
答案 0 :(得分:0)
这是合乎逻辑的。为了您的需求,请按国家/地区名称获取国家/地区。如果存在,则将其设置在城市对象中。
@PostMapping(value = "/cities")
public void insertCities(@RequestBody @Valid City city)
{
Country country = countryRepository.findByName(city.getCountry().getName());
if(country != null) city.setCountry(country);
cityRepository.save(city);
}
还有findByName
中的CountryRepository
Country findByName(String name);