Java @OneToMany不为现有的孩子们提供服务

Java @OneToMany不为现有的孩子们提供服务,java,spring,hibernate,rest,spring-boot,Java,Spring,Hibernate,Rest,Spring Boot,我有使用Hibernate归档@manytone关系的代码。我有两个班,包裹和地址。在地址中,我希望有唯一的条目,其中每个地址都不同于其他地址。然后我有一个正在使用它的包 @Entity public class Address { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false, updatable = false) private Lon

我有使用Hibernate归档@manytone关系的代码。我有两个班,包裹和地址。在地址中,我希望有唯一的条目,其中每个地址都不同于其他地址。然后我有一个正在使用它的包

@Entity
public class Address {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id", nullable = false, updatable = false)
  private Long id;

  String street_with_number;
  String city;
  String region;
  //...
}

@Entity 
public class Package {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id", nullable = false, updatable = false)
  private Long id;

  String eshopId;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name="destination_address_id")
  private Address destination_address;

  //...
}
然后,我有JpaRepository创建回购:

@RepositoryRestResource
public interface PackageRepository extends JpaRepository<Package, Long> {
   //...
  }
这将在表包中创建一个条目,在地址中创建一个条目,并且目标地址id指向正确的Address.id。然后我再次发送相同的JSON,hibernate创建了与之前相同的新地址,它没有重用它


我希望hibernate检查地址是否存在,如果存在,它不会在表地址中创建新行,而是使用已经存在的那个行。这有可能吗?这种行为会创建两个重复的行,但ID不同,这不是我想要的。谢谢你的帮助

您必须检查此地址是否已由您自己定义。没有Hibernate机制可以为您做到这一点

我建议您使用getOrCreate方法创建一个AddressService,该方法将检查是否有一个包含传递数据的地址,或者是否应该创建该地址。这对您来说是一种业务规则,因此在控制器和存储库之间提供一个附加层感觉是个好主意

@RestController
@RequestMapping("/api/")
public class RestController {
  private PackageRepository packageRepository;

  @Inject
  public void setRepository(PackageRepository packageRepository) {
    this.packageRepository = packageRepository;
  }

  @RequestMapping(method = RequestMethod.POST)
  public ResponseEntity<?> addPack(@RequestBody Package pack) {
    return new ResponseEntity<>(packageRepository.save(pack), HttpStatus.CREATED);
  }
}
{
   "eshopId" : 1,
   "destination_address": {
       "street_with_number": "string",
       "city": "string",
       "region": "string"
   }
}