gpt4 book ai didi

Spring JPA : Issue with shared PK in one-to-one relationship

转载 作者:行者123 更新时间:2023-12-03 22:07:31 26 4
gpt4 key购买 nike

我正在尝试与共享 PK 建立一对一的关系,但是在尝试了很多事情之后我陷入了困境......

我会尽量提供所有可能的信息:

我正在使用的技术:

  • Spring Boot 2.1.5
  • Spring JPA
  • 飞道

  • 数据源配置:
    spring.datasource.url = jdbc:mysql://localhost:3306/customers?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true&useSSL=false
    spring.datasource.username = admin
    spring.datasource.password = root

    spring.jpa.database-platform = org.hibernate.dialect.MySQL5InnoDBDialect
    spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
    spring.jpa.show-sql = true

    数据库模型:
    @Getter
    @Setter
    @NoArgsConstructor
    @Entity
    @Table(name = "customer", schema = "customers")
    public class Customer {

    @Id
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "uuid2")
    @Column(name = "customer_id", columnDefinition = "BINARY(16)")
    private UUID customerId;

    @OneToOne(mappedBy = "customer", cascade = CascadeType.ALL)
    private Address address;
    }

    @Getter
    @Setter
    @NoArgsConstructor
    @Entity
    @Table(name = "address", schema = "customers")
    public class Address {

    @Id
    @Column(name = "address_id", columnDefinition = "BINARY(16)")
    private UUID addressId;

    @OneToOne(fetch = FetchType.LAZY)
    @MapsId
    private Customer customer;
    }

    Flyway 迁移文件:
    CREATE SCHEMA IF NOT EXISTS CUSTOMERS;

    CREATE TABLE CUSTOMERS.CUSTOMER
    (
    customer_id BINARY(16) NOT NULL PRIMARY KEY,
    ) ENGINE = InnoDB;

    CREATE TABLE CUSTOMERS.ADDRESS
    (
    address_id BINARY(16) NOT NULL PRIMARY KEY,
    ) ENGINE = InnoDB;

    ALTER table CUSTOMERS.ADDRESS
    ADD CONSTRAINT fk_customer_address
    FOREIGN KEY (address_id)
    REFERENCES CUSTOMERS.CUSTOMER (customer_id);

    集成测试:
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class CustomerRepositoryIntegrationTest {

    @Autowired
    private CustomerRepository cut;

    @Test
    public void testSaveAndDeleteCustomer() {
    Address address = new Address();
    Customer customer = new Customer();
    customer.setAddress(address);

    cut.save(customer);

    Customer retrievedCustomer = cut.findAll().get(0);
    assertEquals(customer, retrievedCustomer);
    }
    }

    错误:
    ERROR] testSaveAndDeleteCustomer(com.foxhound.customers.repositories.CustomerRepositoryIntegrationTest)  Time elapsed: 0.034 s  <<< ERROR!
    org.springframework.orm.jpa.JpaSystemException: attempted to assign id from null one-to-one property [com.foxhound.customers.models.Address.customer]; nested exception is org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [com.foxhound.customers.models.Address.customer]
    at com.foxhound.customers.repositories.CustomerRepositoryIntegrationTest.testSaveAndDeleteCustomer(CustomerRepositoryIntegrationTest.java:47)
    Caused by: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [com.foxhound.customers.models.Address.customer]
    at com.foxhound.customers.repositories.CustomerRepositoryIntegrationTest.testSaveAndDeleteCustomer(CustomerRepositoryIntegrationTest.java:47)

    预先感谢您的帮助。

    干杯!

    最佳答案

    您不了解双向映射的工作原理,因此您需要仔细考虑。编码

    @OneToOne(fetch = FetchType.LAZY)
    @MapsId
    private Customer customer;

    Address使映射单向。通常为了保存它,您需要设置 customer字段并保存。
    address.setCustomer(customer);        
    addressRepo.save(address);

    但是,您已经定义了双向映射并提供了级联注释。
    @OneToOne(mappedBy = "customer", cascade = CascadeType.ALL)
    private Address address;

    级联注释使您不必执行两个持久性操作(在您的代码中),但这并不意味着您不必在地址中设置客户字段。此外,正如您所注意到的,为了使级联操作起作用,您需要设置客户的地址字段。
    customer.setAddress(address);

    因此,为了使代码正常工作,您需要更改它以在地址中设置客户。
    Address address = new Address();
    Customer customer = new Customer();
    customer.setAddress(address);
    address.setCustomer(customer);
    customerRepo.save(customer);

    使用双向映射,您必须管理关系的双方或以单向方式使用它进行持久化,并以双向方式使用它进行检索。如果您添加级联注释,那么您还必须管理关系的双方以进行持久化。

    关于 Spring JPA : Issue with shared PK in one-to-one relationship,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56393839/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com