我不是springboot/hhibernate jpa的专业人员,所以我提前道歉。
我有两个实体,一个叫Document,另一个叫Bgo。Document是父表,Bgo是子表。因此,我的目标是创建文档,之后,Bgo将收到它的id,例如:当我创建第一个Document时,它的id_Document=1,因此在那之后,Bgo也将具有id_Document=1。我想用父母的id填充孩子的id。
这是母公司:
package com.testing.testing.models;
import java.io.Serializable;
import java.sql.Date;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name = "DOCUMENT")
public class Document implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id_document;
private int num_document;
private Date date;
@OneToOne(mappedBy = "document", cascade = CascadeType.ALL)
private Bgo bgo;
public Document() {
}
public Document(Bgo bgo) {
this.id_document = bgo.getId_document();
this.bgo = bgo;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Bgo getBgo() {
return bgo;
}
public void setBgo(Bgo bgo) {
this.bgo = bgo;
}
public long getId_document() {
return id_document;
}
public void setId_document(long id_document) {
this.id_document = id_document;
}
public int getNum_document() {
return num_document;
}
public void setNum_document(int num_document) {
this.num_document = num_document;
}
}
儿童实体:
package com.testing.testing.models;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
@Entity
@Table(name = "BGO")
public class Bgo implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private long id_document;
private String name_bgo;
private int num_bgo;
@OneToOne
@PrimaryKeyJoinColumn(name = "id_document", referencedColumnName = "id_document")
private Document document;
public Bgo() {
}
public Bgo(Document document) {
this.id_document = document.getId_document();
this.document = document;
}
public long getId_document() {
return id_document;
}
public void setId_document(long id_document) {
this.id_document = id_document;
}
public String getName_bgo() {
return name_bgo;
}
public void setName_bgo(String name_bgo) {
this.name_bgo = name_bgo;
}
public int getNum_bgo() {
return num_bgo;
}
public void setNum_bgo(int num_bgo) {
this.num_bgo = num_bgo;
}
public Document getDocument() {
return document;
}
public void setDocument(Document document) {
this.document = document;
}
}
我使用了术语PrimaryKeyJoinColumn,因为我希望Bgo的id是文档的id,这就是为什么我也使用了相同的名称";id_document";。因此,Bgo的id将同时是Primary和Foreign(如果是错误的,请告诉我更好的方法,知识总是受欢迎的(
我还有文档库:
package com.testing.testing.repository;
import com.testing.testing.models.Document;
import org.springframework.data.jpa.repository.JpaRepository;
public interface DocumentRepository extends JpaRepository<Document, Long> {
}
和Bgo的:
package com.testing.testing.repository;
import com.testing.testing.models.Bgo;
import org.springframework.data.jpa.repository.JpaRepository;
public interface BgoRepository extends JpaRepository<Bgo, Long> {
}
文件管理员:
package com.testing.testing.controllers;
import java.util.List;
import com.testing.testing.models.Document;
import com.testing.testing.repository.DocumentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value="/document")
public class DocumentController {
@Autowired
DocumentRepository documentRepository;
@GetMapping
public List<Document> listDocument() {
return documentRepository.findAll();
}
@PostMapping
public Document createDocument(@RequestBody Document document) {
return documentRepository.save(document);
}
}
Bgo的控制器:
package com.testing.testing.controllers;
import java.util.List;
import com.testing.testing.models.Bgo;
import com.testing.testing.repository.BgoRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value="/bgo")
public class BgoController {
@Autowired
BgoRepository bgoRepository;
@GetMapping
public List<Bgo> listBgo() {
return bgoRepository.findAll();
}
}
所以基本上,问题是:在此处输入图像描述
当我创建一个新的Document和Bgo对象时,Bgo的id是0,正如你在图像中看到的,对象Bgo具有";id_ document=0";,它不应该是id_document=1吗?
当我尝试列出Bgo时,它仍然显示id_document=0:在此处输入图像描述
这就是我想要的数据库:在此处输入图像描述
正如你所看到的,它们是不同的表格。但是Document有主键并且是父项,Bgo是子项,因为它正在接收Document的id。正如你所看到的,Bgo有Document的id,它同时是主键和外键,这就是我使用PrimaryKeyJoinColumn的原因。它们都有相同的id,Document的id等于Bgo的id。因此,每当我同时创建Document和Bgo时,它们都应该有相同的id。
您可能需要使用Spring附带的继承功能。看看这个:https://www.baeldung.com/hibernate-inheritance
例如,您可以使用@Heritage(策略=InheritanceType.SINGLE_TABLE(在您的父表上。然后您将仅使用@Entity注释子项然后,您将像在正常继承场景中一样扩展它
,这样您的父类将看起来像这样:
import java.sql.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.Table;
import javax.persistence.InheritanceType;
@Entity
@Table(name = "Document")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Document {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Id")
private Integer Id;
@Column(name = "num_document")
private int num_document;
@Column(name = "date")
private Date date;
public Document() {
}
public Document( int num_document, Date date) {
super();
this.num_document = num_document;
this.date = date;
}
}
孩子会看起来像
import java.sql.Date;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "Bgo")
public class Bgo extends Document {
@Column(name = "name_bgo")
private String name_bgo;
@Column(name = "num_bgo")
private int num_bgo;
public Bgo(String name_bgo, int num_bgo) {
super();
this.name_bgo = name_bgo;
this.num_bgo = num_bgo;
}
public Bgo() {
super();
}
}
你会有一个JPAR的存款,看起来是这样的;
import org.springframework.data.jpa.repository.JpaRepository;
public interface DocumentRepository extends JpaRepository<Document, Integer> {
}
此代码的结果将在数据库中生成一个表,其中包含一个额外的列dtype,该列dtype将标识记录为Bgo或将来可能需要添加的任何其他类型。这就是继承背后的理念
我希望这能帮助
以下是您使用spring的三种不同继承策略单个映射是默认映射它对父类使用@heritage(strategy=InheritanceType.SINGLE_TABLE(注释在这种策略中,父类是一个表,它的所有子类都将在父表的鉴别器列中指定。名为dtype的列,它包含实体的名称作为值。每个类的表策略类似于超类策略,但超类也是一个实体,如果你想进行这么多联接查询,你需要避免这个实体联接表策略的使用方法与上述相同。在这种策略中,子类和超类都将是数据库中的表,但子类不会继承超类的字段,如果我们想在一些字段上应用数据完整性和null约束,这是很有用的
有关更多详细信息,请查看此处https://thorben-janssen.com/complete-guide-inheritance-strategies-jpa-hibernate/选择一个适合您的情况,然后您就可以使用我在第一个答案中提供的实现,您只需要更改这个注释@继承(策略=继承类型.SINGLE_TABLE(