JPA Hibernate在两个表之间拆分数据

时间:2018-11-07 16:15:46

标签: spring hibernate spring-boot jpa

我有一个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的基础知识,您的回答将引导我朝正确的方向发展,以避免诸如“重新发明轮子”之类的事情。

非常感谢!

2 个答案:

答案 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;