两个可选的一对一MapHibernate

k2arahey  于 2023-10-23  发布在  其他
关注(0)|答案(1)|浏览(91)

我正在尝试构建一个与银行活动相关的示例项目。
客户可以是个人(财务人员)或法律的实体(企业),也可以开立银行账户。
我创建了4个表:

*客户类型
*客户
*customer_individual
*customer_法律的_entity

这个想法是,除了id之外,Customer只有一个Mapcustomer_type的外键。
在db上必须保存新客户时,customer表(id_customer)值的pk必须设置为:

  • id_customer_individual如果客户是个人
  • id_customer_法律的_entity(如果客户是法律的实体)

为了避免冲突,id_customer_individual和id_customer_法律的_entity使用相同的序列来生成id值。
根据customer_type,客户有两个一对一的可选关系

  • 与customer_individual的一对一关系
  • 与客户法律的实体的一对一关系

客户类型:

@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@AttributeOverride(name = "id", column = @Column(name = "id_customer_type", nullable = false))
@Table(name = "customer_type")
public class CustomerType extends TypeEntity {

}

客户:

@Data
@Entity
@Table(name = "customer")
public class Customer {

    @Id
    @Column(name = "id_customer", nullable = false)
    private Long id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "fk_customer_type", nullable = false)
    private CustomerType customerType;

    @OneToOne(fetch = FetchType.LAZY, optional = true)
    @MapsId
    private CustomerIndividual customerIndividual;

    @OneToOne(fetch = FetchType.LAZY, optional = true)
    @MapsId
    private CustomerLegalEntity customerLegalEntity;

}

客户个人:

@Data
@Entity
@Table(name = "customer_individual")
public class CustomerIndividual {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "id_customer_seq")
    @SequenceGenerator(name = "id_customer_seq", sequenceName = "id_customer_seq", allocationSize = 1)
    @Column(name = "id_customer_individual", nullable = false)
    private Long id;

    @Column(name = "fk_nationality", nullable = false)
    private Integer fkNationality;

    @Column(name = "fk_residence", nullable = false)
    private Long fkResidence;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "fk_sex_type", nullable = false)
    private SexType sexType;

    @Column(name = "birth_date", nullable = false)
    private LocalDate birthDate;

    @Column(name = "name", nullable = false)
    private String name;

    @Column(name = "surname", nullable = false)
    private String surname;

    @Column(name = "email", nullable = false)
    private String email;

    @Column(name = "phone_number", nullable = false)
    private String phoneNumber;
    
}

客户合法实体:

@Data
@Entity
@Table(name = "customer_legal_entity")
public class CustomerLegalEntity {

    @Id
    @Column(name = "id_customer_legal_entity", nullable = false)
    private Long id;

    @NotNull
    @Column(name = "fk_headquarters", nullable = false)
    private Long fkHeadquarters;

    @NotNull
    @Column(name = "name", nullable = false, length = Integer.MAX_VALUE)
    private String name;

}

我首先保存一个CustomerIndividual,然后创建一个新的Customer示例并设置必要的字段。

Customer customer = new Customer();
customer.setCustomerType(customerTypeService.getReferenceById(1));
customer.setCustomerIndividual(customerIndividual);
return customerRepository.save(customer);

但是在保存Customer时,会抛出以下异常:

Caused by: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [com.hyperbank.accounts.customer.entity.Customer.customerLegalEntity]
xxls0lw8

xxls0lw81#

我将SequenceGenerator移到了Customerid,并将可选的一对一关系从Customer移到了CustomerIndividualCustomerLegalEntity
客户:

@Data
@Entity
@Table(name = "customer")
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "id_customer_seq")
    @SequenceGenerator(name = "id_customer_seq", sequenceName = "id_customer_seq", allocationSize = 1)
    @Column(name = "id_customer", nullable = false)
    private Long id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "fk_customer_type", nullable = false)
    private CustomerType customerType;

}

客户个人:

@Data
@Entity
@Table(name = "customer_individual")
public class CustomerIndividual {

    @Id
    @Column(name = "id_customer", nullable = false)
    private Long id;

    @Column(name = "fk_nationality", nullable = false)
    private Integer fkNationality;

    @Column(name = "fk_residence", nullable = false)
    private Long fkResidence;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "fk_sex_type", nullable = false)
    private SexType sexType;

    @Column(name = "birth_date", nullable = false)
    private LocalDate birthDate;

    @Column(name = "name", nullable = false)
    private String name;

    @Column(name = "surname", nullable = false)
    private String surname;

    @Column(name = "email", nullable = false)
    private String email;

    @Column(name = "phone_number", nullable = false)
    private String phoneNumber;
    
    @OneToOne(fetch = FetchType.LAZY, orphanRemoval = true)
    @JoinColumn(name = "id_customer")
    @MapsId
    private Customer customer;
    
}

客户合法实体:

@Data
@Entity
@Table(name = "customer_legal_entity")
public class CustomerLegalEntity {

    @Id
    @Column(name = "id_customer", nullable = false)
    private Long id;

    @NotNull
    @Column(name = "fk_headquarters", nullable = false)
    private Long fkHeadquarters;

    @NotNull
    @Column(name = "name", nullable = false)
    private String name;

    @OneToOne(fetch = FetchType.LAZY, orphanRemoval = true)
    @JoinColumn(name = "id_customer")
    @MapsId
    private Customer customer;
    
}

在服务上,我首先保存客户,然后将其设置为CustomerIndividual,CustomerIndividual的ID正确地反映了Customer的ID。

public CustomerIndividual save(CustomerIndividual entity) {
    Customer customer = customerService.saveWithTypeCustomerIndividual();
    entity.setCustomer(customer);
    entity = repository.save(entity);
    return entity;
}

相关问题