gpt4 book ai didi

java - 了解 Hibernate 连接表

转载 作者:行者123 更新时间:2023-12-02 09:09:00 26 4
gpt4 key购买 nike

我有两个具有一对多关系的实体,如下所示。除了删除操作之外,一切正常。删除时,我收到错误:关系“a_b”不存在。为此,我找到了解决方案 here .

根据答案,关系存在问题,hibernate 将关系视为单独的单向关系,它将创建第三个表 a_b 并独立跟踪关系的双方。为了解决这个问题,我添加了 ma​​ppedBy = "a"

问题是

为什么 hibernate 会触发表 a_b 的删除查询,而在创建新记录时不会插入到 a_b 中?

登录插入

Hibernate: insert into a...
Hibernate: insert into b...
Hibernate: insert into b...
Hibernate: insert into b...
**Why insert into a_b... is not generated/inserted?**

登录删除

Hibernate: select a0_.id as id1_11_, from a a0_ where (a0_.id in (?))?
Hibernate: delete from b where a_id in (?)
Hibernate: delete from a_b where (a_id) in (select id from a where id in (?))
**Why delete from a_b if nothing is inserted into a_b**

12:19:50.432 [XNIO-1 task-20] WARN o.h.e.jdbc.spi.SqlExceptionHelper - SQL Error: 0, SQLState: 42P01
12:19:50.433 [XNIO-1 task-20] ERROR o.h.e.jdbc.spi.SqlExceptionHelper - ERROR: relation "a_b" does not exist

with cause = 'org.hibernate.exception.SQLGrammarException: could not execute statement' and exception = 'could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement'

实体A

@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;

.....

}

实体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;

.....
}

AServiceImpl

@Override
public int delete(List<Long> ids) {
...
bRepository.deleteWithIds(ids);
aRepository.deleteWithIds(ids);
}

B存储库

@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);
<小时/>

当前代码

实体A

@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;

.....

}

实体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;

.....
}
<小时/>

编辑:插入序列

  1. 保存实体A

    aRepository.saveAndFlush(a);

  2. 调用第三方 API 并基于响应集实体 A用于保存实体B

    x.forEach(b-> {
    b.setA(aRepository.findById(aId).get());
    bRepository.save(b);
    });

最佳答案

可以考虑很多场景如果您使用单向 oneToMany 映射,则需要一个联接表来保存关系。因为,单个 A 实体与多个 B 实体关联,并且由于其单向性质,它不具有B 表中的映射列。在此处输入代码

@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;
}
}

在上面的情况下,它是单向的 oneToMany,并且需要一个连接表。

如果你像这样保存你的实体 在此处输入代码

 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);

这会将关系映射保存在连接表中。

情况 2:- 现在,如果您在 B 实体类中添加以下内容,它将为 A 表创建一个外键列。这将再次是单向 ManyToOne 映射。

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);

这不会将关系保存在连接表中,而是使用表 B 中名为 A_ID 的列中存在的外键。

情况 3:- 双向 oneToMany

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;
}
}

上面的实体映射是双向的 oneToMany,并且不使用连接表。

关于java - 了解 Hibernate 连接表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59559699/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com