如何在保存之前代理引用的实体?



我正在使用Spring Boot 2.3.0以及Spring Data JPA和Spring MVC。我有以下 2 个实体:

国家.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)
}

城市.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调用拯救城市。一个问题是,我希望在请求正文中仅提供国家/地区的名称,如果国家/地区存在于国家/地区表中,那么它必须能够自己找到引用,否则它应该首先插入一个新国家/地区,然后匹配引用。

为了完整参考,让我提供存储库和控制器类:

城市存储库.java

@Repository
public interface CityRepository extends JpaRepository<City,Integer>
{
}

主控制器.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代理,因为它还不是一个持久的实体。有没有办法使用数据JPA轻松解决这个问题?还是我应该再低一个级别,玩实体经理?完整的代码示例将不胜感激。

这是合乎逻辑的。对于您想要的功能,请按国家/地区名称获取国家/地区。如果存在,则在城市对象中设置它。

@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);

最新更新