我有一个REST API,它将以以下格式接收一些客户数据:
{
"customer_Id": 50,
"name": "name",
"company_name": "company_name",
"email": "email@provider.com",
"business_phone": "(00) 1111-2222",
"mobile_phone": "(00) 1111-2222",
"document": "123456789",
"state_registration_number": "ISENTO",
"state_registration_type": "NO_CONTRIBUTOR",
"city_registration_number": "ISENTO",
"classification": "AUTO",
"address": {
"street": "STREET NAME XXX",
"number": "NUMBER XX",
"complement": "COMPLEMENT",
"zip_code": "ZIP_CODE",
"neighborhood": "NEIGHBORHOOD",
"city": "CITY",
"state": "STATE"
}
}
我想将此数据保存在两个表中:一个表应包含“主要”客户数据,而另一个表应包含该客户的“地址”数据。
因此,我定义了Customer
实体,如下所示:
@Data
@Entity(name = "X_CUSTOMERS")
public class Customer {
@Id
private int customer_Id;
@NotNull
private String name;
private String company_name;
private String email;
private String business_phone;
private String mobile_phone;
@NotNull
private String document;
private String state_registration_number;
private String state_registration_type;
private String city_registration_number;
@NotNull
private String classification;
@OneToOne(cascade = CascadeType.ALL)
private Address address;
}
Address
实体为
@Data
@Entity(name = "X_ADDRESS")
public class Address {
@NotNull
private String street;
private String number;
private String complement;
private String zip_code;
private String neighborhood;
private String city;
private String state;
}
但是,我不知道如何在它们之间建立关系。是否应该在customer_id
实体上创建Address
属性?我应该在Customer
的{{1}}属性上定义一些其他标签吗?请注意,我在REST客户端发布的JSON数据上没有客户,并且,如果客户是“更新或删除”,则地址数据也应同时更新/删除。
很抱歉,如果这是一个如此琐碎的问题。这些天,我正在学习JPA / Hibernate的基础知识,您的回答将引导我朝正确的方向发展,以避免诸如“重新发明轮子”之类的事情。
非常感谢!
答案 0 :(得分:2)
如果我们认为Address是一个值对象而不是实体,则可以按以下方式映射它。在您的情况下,将其建模为VO可能是正确的:如果您正在构建地址数据库,则可以将其视为实体。在此处进一步查看:
Value vs Entity objects (Domain Driven Design)
然后我们可以将地址类设置为@Embeddable
而不是实体:这样,它就不会拥有自己的任何标识。为了将客户和地址详细信息存储在单独的表中,我们还可以使用JPA @SecondaryTable
功能:
https://docs.oracle.com/javaee/7/api/javax/persistence/SecondaryTable.html
然后有如下模型类。通过这些映射,您的JSON更新将按预期工作。
客户:
@Data
@Table(name = "customers")
@SecondaryTable(name = "customer_addresses", pkJoinColumns={
@PrimaryKeyJoinColumn(name="customer_id",
referencedColumnName="customer_id")})
public class Customer {
protected static final String ADDRESS_TABLE_NAME = "customer_addresses";
// other fields
@Embedded
private Address address;
}
地址:
@Data
@Embeddable
public class Address {
@NotNull
@Column(table = Customer.ADDRESS_TABLE_NAME)
private String street;
@Column(table = Customer.ADDRESS_TABLE_NAME)
private String number;
@Column(table = Customer.ADDRESS_TABLE_NAME)
private String complement;
@Column(table = Customer.ADDRESS_TABLE_NAME)
private String zip_code;
@Column(table = Customer.ADDRESS_TABLE_NAME)
private String neighborhood;
@Column(table = Customer.ADDRESS_TABLE_NAME)
private String city;
@Column(table = Customer.ADDRESS_TABLE_NAME)
private String state;
}
答案 1 :(得分:0)
这就是我的方法:
@OneToOne (fetch=FetchType.EAGER, cascade = CascadeType.ALL, optional = false)
@NotNull(message = "L'addresse du domicile est requise!", groups = Seventh.class)
@Getter
@Setter
private Address homeAddress;
不需要任何逆映射,这使我可以一口气保存一个客户及其地址!
您还需要您的地址实体的ID,例如:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(unique = true, nullable = false)
@Getter
@Setter
private Long id;