spring引导数据jpa:与共享主键的一对一关系

iqih9akk  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(355)

我是新的 Spring 启动数据jpa。我正在测试 Customer 以及 Phone 实体:

@Entity
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String firstName;
    private String lastName;

    @OneToOne(mappedBy = "customer")
    @PrimaryKeyJoinColumn
    private Phone phone;

    // Constructors, getters, and setters
}
@Entity
public class Phone {
    @Id
    private Long id;

    private String number;

    @OneToOne
    @MapsId
    @JoinColumn(name = "id")
    private Customer customer;

    // Constructors, getters, and setters
}

这是你的名字 application.properties :

spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/springtest?createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.show-sql=true

当我运行简单测试时:

@SpringBootTest
class SpringTestApplicationTests {
    @Autowired
    private CustomerRepository customerRepository;

    @Autowired
    private PhoneRepository phoneRepository;

    @Test
    public void test() {
        customerRepository.deleteAll();
        phoneRepository.deleteAll();

        final Customer customer = new Customer();
        customer.setFirstName("John");
        customer.setLastName("Doe");

        customerRepository.save(customer);

        final Phone phone = new Phone();
        phone.setNumber("1234567890");
        phone.setCustomer(customer);

        phoneRepository.save(phone);
    }
}

最后一行代码( phoneRepository.save(phone) )引发此异常:

org.springframework.dao.InvalidDataAccessApiUsageException: 
detached entity passed to persist: org.code.entities.Customer

我在google上搜索了这个异常,但仍然无法解决这个问题。谢谢你的帮助。
一些可能有用的附加信息:
Spring Boot2.4.0
java 11
使用生成项目https://start.spring.io/

m2xkgtsf

m2xkgtsf1#

我能让它工作。这是细节。两者之间的关系 Customer 以及 Phone 实体是双向的和一对一的。注意 Phone 是关系的拥有方,因为它的主键不是自动生成的,而且它的主键也是关系的外键 Customer 实体。示例化这些实体后,我们必须通过以下行交叉引用另一个实体中的每个对象:

phone.setCustomer(customer);
customer.setPhone(phone);

然后,我们必须首先保存phone对象,然后保存customer对象。
以下是新的测试:

@SpringBootTest
class SpringTestApplicationTests {
    @Autowired
    private CustomerRepository customerRepository;

    @Autowired
    private PhoneRepository phoneRepository;

    @Test
    public void test() {
        phoneRepository.deleteAll();
        customerRepository.deleteAll();

        final Customer customer = new Customer();
        customer.setFirstName("John");
        customer.setLastName("Doe");

        final Phone phone = new Phone();
        phone.setNumber("1234567890");
        phone.setCustomer(customer);
        customer.setPhone(phone);

        phoneRepository.save(phone);
        customerRepository.save(customer);
    }
}

相关问题