Java 理解Hibernate连接表
我有两个具有一对多关系的实体,如下所示。除删除操作外,所有操作都正常。删除时,我得到错误:关系a_b不存在。为此,我找到了解决办法 根据回答,关系存在问题,hibernate将关系视为单独的单向关系,它将创建第三个表a_b并独立跟踪关系的双方。为了解决这个问题,我添加了mappedBy=a 问题是 为什么hibernate在创建新记录时不插入表a_b,却触发表a_b的删除查询 登录插入 登录删除 实体A AServiceImpl 编辑:插入序列 保存实体A aRepository.saveAndFlusha 调用第三方API并基于响应集实体a 用于保存实体B x、 forEachb->{ b、 setAaRepository.findByIdaId.get; bRepository.saveb; };Java 理解Hibernate连接表,java,spring,hibernate,spring-boot,Java,Spring,Hibernate,Spring Boot,我有两个具有一对多关系的实体,如下所示。除删除操作外,所有操作都正常。删除时,我得到错误:关系a_b不存在。为此,我找到了解决办法 根据回答,关系存在问题,hibernate将关系视为单独的单向关系,它将创建第三个表a_b并独立跟踪关系的双方。为了解决这个问题,我添加了mappedBy=a 问题是 为什么hibernate在创建新记录时不插入表a_b,却触发表a_b的删除查询 登录插入 登录删除 实体A AServiceImpl 编辑:插入序列 保存实体A aRepository.saveAnd
可以考虑很多情况。 如果您使用单向的oneToMany映射,则需要一个联接表来保存关系。由于单个a实体与多个B实体关联,并且由于其单向性,因此在B表中没有映射列。请在此处输入代码 这将在联接表中保存关系映射 案例2:-现在,如果在B实体类中添加以下内容,它将在表中创建一个外键列。这将再次成为单向多通映射
enter code here
@ManyToOne()
A a;
如果你能做到以下几点
enter code here
A a =new A();
B b =new B();
b.setA(a);
B b1=new B();
b1.setA(a);
bRepository.save(b);
bRepository.save(b1);
这不会将关系保存在联接表中,而是使用名为A_ID的表B列中的外键
案例3:双向一家公司
上面的实体映射是双向的oneToMany,不使用联接表。在这里需要小心。表a_b或其真实名称是一个连接表,如果我没有记错的话,它是由Hibernate自动生成的,以适应多对一关系。我不确定您是否应该直接对此表发出删除命令;从ORM的角度来看,它实际上并不存在。您是否尝试过@OneToManycascade=CascadeType.ALL?谢谢@TimBiegeleisen,hibernate是否会在添加mappedBy=a后生成连接表?根据答案,我已经链接了它,不应该在添加了拥有方之后创建它。我添加了删除呼叫以了解更多详细信息。你能分享更多关于它的细节吗?不幸的是,我的专业知识或多或少随着我上面的评论而停止。首先,检查底层数据库,看看Hibernate对它做了什么。理想情况下,您不必像我上面提到的那样在Hibernate中从连接表中删除。相反,如果您删除了关系的正确部分,Hibernate应该能够使用级联删除来清除所有表中的所有内容。请编辑您的问题并为其提供更好的标题。对Hibernate ORM的理解过于笼统和模糊,不能告诉我们您的实际问题。
@Entity
@Table(name = "a")
public class A extends AbstractAuditingEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@OneToMany
private List<B> b;
.....
}
@Entity
@Table(name = "b")
public class B extends AbstractAuditingEntity implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@ManyToOne
private A a;
.....
}
@Override
public int delete(List<Long> ids) {
...
bRepository.deleteWithIds(ids);
aRepository.deleteWithIds(ids);
}
@Transactional
@Modifying
@Query("delete from b x where x.a.id in :ids")
void deleteLogsWithIds(@Param("ids") List<Long> ids);
@Modifying
@Transactional
@Query("delete from a x where x.id in :ids")
void deleteJobWithIds(@Param("ids") List<Long> ids);
@Entity
@Table(name = "a")
public class A extends AbstractAuditingEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@OneToMany(mappedBy = "a")
private List<B> b;
.....
}
@Entity
@Table(name = "b")
public class B extends AbstractAuditingEntity implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@ManyToOne
private A a;
.....
}
@Entity
@Table(name = "A")
public class A {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
private int id;
private String stateName;
//This is uni-directional since we donot have a corresponding reference to A in B entity
@OneToMany(cascade = CascadeType.ALL)
List<B> bs = new ArrayList<>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public List<B> getBs() {
return bs;
}
public void setBs(List<B> bs) {
this.bs = bs;
}
public String getStateName() {
return stateName;
}
public void setStateName(String stateName) {
this.stateName = stateName;
}
}
@Entity
@Table(name="B")
public class B {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="ID")
private int id;
private String districtName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDistrictName() {
return districtName;
}
public void setDistrictName(String districtName) {
this.districtName = districtName;
}
}
A a= new A();
B b=new B();
B b1=new B();
List<B> bs=new ArrayList<>();
bs.add(b);
bs.add(b1);
aRepository.save(a);
enter code here
@ManyToOne()
A a;
enter code here
A a =new A();
B b =new B();
b.setA(a);
B b1=new B();
b1.setA(a);
bRepository.save(b);
bRepository.save(b1);
enter code here
@Entity
@Table(name = "A")
public class A {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
private int id;
private String stateName;
@OneToMany(mappedBy = "a", cascade = CascadeType.ALL)
List<B> bs = new ArrayList<>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public List<B> getBs() {
return bs;
}
public void setBs(List<B> bs) {
this.bs = bs;
}
public void addB(B b) {
b.setA(this);
bs.add(b);
}
public void removeB(B b) {
b.setA(null);
bs.remove(b);
}
public String getStateName() {
return stateName;
}
public void setStateName(String stateName) {
this.stateName = stateName;
}
}
@Entity
@Table(name = "B")
public class B {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
private int id;
private String districtName;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "A_ID")
A a;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
public String getDistrictName() {
return districtName;
}
public void setDistrictName(String districtName) {
this.districtName = districtName;
}
}