使用 jpa 将数据插入到 2 个连接表中
Posted
技术标签:
【中文标题】使用 jpa 将数据插入到 2 个连接表中【英文标题】:inserting data to 2 joined tables using jpa 【发布时间】:2021-11-01 17:27:56 【问题描述】:我是 sring boot 和 jpa 的新手,所以我正在尝试制作一个采用 cutomer 类和电话号码类的 api
客户:
package com.phonenumbers.phonenumbers.entity;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import javax.persistence.*;
@Entity
@Table(name = "customer")
public class Customer
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "c_name", nullable = false)
private String name;
@Column(name = "c_address", nullable = false)
private String address;
@OneToOne(targetEntity = Phonenumber.class,mappedBy = "customer", cascade = CascadeType.ALL)
private Phonenumber phone;
public Customer()
@Override
public String toString()
return "Customer" +
"id=" + id +
", name='" + name + '\'' +
", address='" + address + '\'' +
", phone=" + phone +
'';
public long getId()
return id;
public void setId(long id)
this.id = id;
public String getName()
return name;
public void setName(String name)
this.name = name;
public String getAddress()
return address;
public void setAddress(String address)
this.address = address;
public Phonenumber getPhone()
return phone;
public void setPhone(Phonenumber phone)
this.phone = phone;
public Customer( String name, String address, Phonenumber phone)
this.name = name;
this.address = address;
this.phone = phone;
电话号码:
package com.phonenumbers.phonenumbers.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "phonenumber")
public class Phonenumber
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "p_number", nullable = false)
private String number;
@Column(name = "c_code", nullable = false)
private String ccode;
@Column(name = "c_name", nullable = false)
private String cname;
@Column(name = "o_name", nullable = false)
private String oname;
public Phonenumber()
public Phonenumber(String number, String ccode, String cname, String oname)
super();
this.number = number;
this.ccode = ccode;
this.cname = cname;
this.oname = oname;
public long getId()
return id;
public void setId(long id)
this.id = id;
public String getNumber()
return number;
public void setNumber(String number)
this.number = number;
public String getCcode()
return ccode;
public void setCcode(String ccode)
this.ccode = ccode;
public String getCname()
return cname;
public void setCname(String cname)
this.cname = cname;
public String getOname()
return oname;
public void setOname(String oname)
this.oname = oname;
@Override
public String toString()
return "Phonenumber [id=" + id + ", number=" + number + ", ccode=" + ccode + ", cname=" + cname + ", oname="
+ oname + "]";
客户控制器:
package com.phonenumbers.phonenumbers.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.phonenumbers.phonenumbers.entity.Customer;
import com.phonenumbers.phonenumbers.repository.CustomerRepository;
@RestController
@RequestMapping("/api/v1")
@CrossOrigin
public class CustomerController
@Autowired
private CustomerRepository customerrepository;
@GetMapping("/customer1")
public List<Customer> getAllCustomers()
return customerrepository.findAll();
@GetMapping("/customer6/id")
public Optional<Customer> getcustomerById(@PathVariable(value = "id") Long customerid)
return customerrepository.findById(customerid);
@PostMapping("/customer")
public Customer create (@RequestBody Customer newcustomer)
return customerrepository.save(newcustomer);
// @PutMapping("/customer3/id")
// public ResponseEntity<Customer> update(@PathVariable(value = "id") Long customerid,
// @RequestBody Customer numberDetails)
// Customer x = customerrepository.getById(customerid);
//
// x.setName(numberDetails.getName());
// x.setAddress(numberDetails.getAddress());
// x.setPhoneid(numberDetails.getPhoneid());
//
// final Customer updatedcustomer = customerrepository.save(x);
// return ResponseEntity.ok(updatedcustomer);
//
@DeleteMapping("/customer2/id")
public Map<String, Boolean> delete(@PathVariable(value = "id") Long customerid)
Customer u = customerrepository.getById(customerid);
customerrepository.delete(u);
Map<String, Boolean> response = new HashMap<>();
response.put("deleted", Boolean.TRUE);
return response;
电话号码控制器:
package com.phonenumbers.phonenumbers.controller;
import java.util.HashMap;
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.phonenumbers.phonenumbers.entity.Phonenumber;
import com.phonenumbers.phonenumbers.repository.PhoneNumberRepository;
@SuppressWarnings("unused")
@RestController
@RequestMapping("/api/v1")
public class PhonenumberController
@Autowired
private PhoneNumberRepository phonenumberrepository;
@GetMapping("/phonenumber")
public List<Phonenumber> getAllPhonenumbers()
return phonenumberrepository.findAll();
@GetMapping("/phonenumber/id")
public ResponseEntity<Phonenumber> getnumberById(@PathVariable(value = "id") Long numberid)
Phonenumber t = phonenumberrepository.getById(numberid);
return ResponseEntity.ok().body(t);
@PostMapping("/phonenumber6")
public Phonenumber create(@RequestBody Phonenumber pnumber)
return phonenumberrepository.save(pnumber);
@PutMapping("/phonenumber1/id")
public ResponseEntity<Phonenumber> update(@PathVariable(value = "id") Long numberid,
@RequestBody Phonenumber numberDetails)
Phonenumber x = phonenumberrepository.getById(numberid);
x.setNumber(numberDetails.getNumber());
x.setCcode(numberDetails.getCcode());
x.setCname(numberDetails.getCname());
x.setOname(numberDetails.getOname());
final Phonenumber updatednumber = phonenumberrepository.save(x);
return ResponseEntity.ok(updatednumber);
@DeleteMapping("/phonenumber2/id")
public Map<String, Boolean> delete(@PathVariable(value = "id") Long numberid)
Phonenumber u = phonenumberrepository.getById(numberid);
phonenumberrepository.delete(u);
Map<String, Boolean> response = new HashMap<>();
response.put("deleted", Boolean.TRUE);
return response;
PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
所以我需要帮助才能知道如何在数据库中插入客户和电话号码,并在客户和电话号码之间建立连接关系,我也遇到了这个错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Unknown mappedBy in: com.phonenumbers.phonenumbers.entity.Customer.phone, referenced property unknown: com.phonenumbers.phonenumbers.entity.Phonenumber.customer
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786) ~[spring-beans-5.3.9.jar:5.3.9]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:602) ~[spring-beans-5.3.9.jar:5.3.9]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.9.jar:5.3.9]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.9.jar:5.3.9]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.9.jar:5.3.9]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.9.jar:5.3.9]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.9.jar:5.3.9]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154) ~[spring-context-5.3.9.jar:5.3.9]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908) ~[spring-context-5.3.9.jar:5.3.9]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.9.jar:5.3.9]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.5.4.jar:2.5.4]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-2.5.4.jar:2.5.4]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[spring-boot-2.5.4.jar:2.5.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:338) ~[spring-boot-2.5.4.jar:2.5.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-2.5.4.jar:2.5.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) ~[spring-boot-2.5.4.jar:2.5.4]
at com.phonenumbers.phonenumbers.PhonenumbersApplication.main(PhonenumbersApplication.java:15) ~[classes/:na]
Caused by: org.hibernate.AnnotationException: Unknown mappedBy in: com.phonenumbers.phonenumbers.entity.Customer.phone, referenced property unknown: com.phonenumbers.phonenumbers.entity.Phonenumber.customer
at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:171) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1693) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1661) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:295) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1224) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1255) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.3.9.jar:5.3.9]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.3.9.jar:5.3.9]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-5.3.9.jar:5.3.9]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-5.3.9.jar:5.3.9]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.3.9.jar:5.3.9]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1845) ~[spring-beans-5.3.9.jar:5.3.9]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782) ~[spring-beans-5.3.9.jar:5.3.9]
... 16 common frames omitted
Process finished with exit code 1
【问题讨论】:
实体Phonenumber
上没有字段customer
,但@OneToOne
注释中的mapedBy = "customer"
暗示了这一点。我建议阅读有关该主题的教程,例如this one over at Baeldung.
所以即使是单向连接?
如果是单向的,那么有@OneToOne
注解的那一边一定是拥有那一边。情况并非如此,因为没有定义 @JoinColumn
并且设置了 mappedBy
-attribute。请阅读我在first comment 中链接的教程。
【参考方案1】:
使用以下映射:
@Entity
@Table(name = "customer")
public class Customer
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "c_name", nullable = false)
private String name;
@Column(name = "c_address", nullable = false)
private String address;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "phone_id")
private Phonenumber phone;
【讨论】:
以上是关于使用 jpa 将数据插入到 2 个连接表中的主要内容,如果未能解决你的问题,请参考以下文章
如何在 php pdo 中使用 1 个表单将数据插入到 2 个不同的表中?