保存前如何代理参考实体?

时间:2020-06-06 12:52:20

标签: java spring hibernate spring-data-jpa

我正在使用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?完整的代码示例将不胜感激。

1 个答案:

答案 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);
相关问题