Java 理解Hibernate连接表

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

我有两个具有一对多关系的实体,如下所示。除删除操作外,所有操作都正常。删除时,我得到错误:关系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; };


可以考虑很多情况。 如果您使用单向的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;
    }
}