让我们看一下表结构:-
CREATE TABLE `customer` (
`id` bigint(20) UNSIGNED AUTO_INCREMENT NOT NULL,
`first_name` varchar(150) COLLATE utf8_unicode_ci NOT NULL,
`last_name` varchar(150) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ALTER TABLE `customer` ADD PRIMARY KEY (`id`);
-------------------------------------------------------------
CREATE TABLE `address` (
`id` bigint(20) UNSIGNED NOT NULL,
`street` varchar(512) COLLATE utf8_unicode_ci NOT NULL,
`city` varchar(512) COLLATE utf8_unicode_ci NOT NULL,
`country` varchar(512) COLLATE utf8_unicode_ci NOT NULL,
`postal_code` varchar(512) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ALTER TABLE `address` ADD PRIMARY KEY (`id`);
地址和客户通过 id
通过一对一关系进行映射。也就是说,customer.id
被分配给 address_id
[我知道表的一列可能充当从其他表生成的主键
]。
让我们看看实体:-
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
@OneToOne
@PrimaryKeyJoinColumn
private Address address;
// getters & setters
@Override
public String toString() {
return String.format(
"Customer[id=%d, firstName='%s', lastName='%s', address='%s']",
id, firstName, lastName, address
);
}
}
//////////////////////////////////////////////////////////////////////////
@Entity
public class Address {
@Id @GeneratedValue(generator = "customForeignGenerator")
@org.hibernate.annotations.GenericGenerator(
name = "customForeignGenerator",
strategy = "foreign",
parameters = @Parameter(name = "property", value = "customer")
)
private Long id;
private String street;
private String city;
private String country;
private String postalCode;
@OneToOne(mappedBy="address")
@PrimaryKeyJoinColumn
public Customer customer;
// getters & setters
@Override
public String toString () {
return String.format(
"Address[id='%d', street='%s', city='%s', country='%s', postalCode='%s']",
id, street, city, country, postalCode
);
}
}
Controller 类:-
@RestController
@RequestMapping("/api/customers")
public class CustomerRestController {
// CustomerRepository extends CrudRepository<Customer, Long>
@Autowired
private CustomerRepository customerRepository;
// AddressRepository extends CrudRepository<Address, Long>
@Autowired
private AddressRepository addressRepository;
@RequestMapping("/customer-with-address/{customerId}")
public Customer getCustomerWithAddress(@PathVariable("customerId") Long customerId) {
return customerRepository.findOne(customerId);
}
@RequestMapping("/save-customer-with-address")
public Customer getCustomer() {
Customer customer = new Customer();
customer.setFirstName("ABC");
customer.setLastName("XYZ");
Customer customer1 = customerRepository.save(customer);
Address address = new Address();
address.setStreet("street " + customer1.getId());
address.setCity("city " + customer1.getId());
address.setCountry("country " + customer1.getId());
address.setPostalCode("postal_code " + customer1.getId());
address.setCustomer(customer1);
addressRepository.save(address);
return customer;
}
}
问题:-
我关注JPA Hibernate One-to-One relationship
/customer-with-address/5
属于递归。如何摆脱递归?/save-customer-with-address
将数据保存到数据库后,将客户对象的地址返回为 null。这是因为地址未设置为客户对象。当我尝试将地址设置为客户对象时,它也陷入递归。那么,如何设置/获取地址对象到客户对象?- 我像以前一样从任何实体完成一对一映射。但这里的映射是从两侧完成的。 我可以从任何方面做吗?
注意:-如果我在 address 表中添加一个额外的列 customer_id
,所有问题都可以轻松解决。但我不想添加 customer_id。我提前感谢您的宝贵意见。
最佳答案
- 检查您是否递归调用方法或对其进行调试
客户中有设置者
设置地址(a){ a.setCustomer(this); 这个地址=a; }
关于java - 在 JPA 中以一对一关系共享主键的情况下如何访问对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41175784/