无法使用@GeneratedValue(IDENTITY)和双向@OneToMany将对象保存到数据库



我在持久化和级联两个实体时遇到了问题,这两个实体都有生成的id。

数据库表

CREATE TABLE [dbo].[CISLO](
[ID_CISLA] [bigint] IDENTITY(1,1) NOT NULL,
constraint PK_CISLO primary key (ID_CISLA)
...omit other columns for brevity

这个表的行为就像绑定一个表一样——它将数字连接到堆栈

CREATE TABLE [dbo].[VAZBA_ZASOBNIK_CISLO](
[ID_VAZBY_ZASOBNIK_CISLO] [bigint] IDENTITY(1,1) NOT NULL,
[ID_ZASOBNIKU] [int] NOT NULL,
[ID_CISLA] [bigint] NOT NULL,
constraint PK_VAZBA_ZASOBNIK_CISLO primary key (ID_VAZBY_ZASOBNIK_CISLO)
...omit other columns for brevity
CREATE TABLE [dbo].[ZASOBNIK](
[ID_ZASOBNIKU] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
constraint PK_ZASOBNIK primary key (ID_ZASOBNIKU)
...omit other columns for brevity

实体看起来像这个

@Getter
@Setter
@ToString
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class Cislo extends AbstractBaseEntity<Cislo, Long> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idCisla;
@ToString.Exclude
@Setter(AccessLevel.NONE)
@OneToMany(mappedBy = "cislo", cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
private Collection<VazbaZasobnikCislo> numberStackRelations = new LinkedList<>();
@Getter
@Setter
@ToString
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class VazbaZasobnikCislo extends AbstractBaseEntity<VazbaZasobnikCislo, Long> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idVazbyZasobnikCislo;
@NotNull
@ToString.Exclude
@JoinColumn(name = "ID_ZASOBNIKU")
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private Zasobnik zasobnik;
@NotNull
@ToString.Exclude
@JoinColumn(name = "ID_CISLA")
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private Cislo cislo;
}
@Getter
@Setter
@ToString
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class Zasobnik extends AbstractBaseEntity<Zasobnik, Integer> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer idZasobniku;
@ToString.Exclude
@Setter(AccessLevel.NONE)
@OneToMany(mappedBy = "zasobnik", cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
private Collection<VazbaZasobnikCislo> numberStackRelations = new LinkedList<>();

现在程序部分

我正在尝试创建数字(Cislo(,并通过创建数字堆栈关系(VazbaZasobnikCislo"堆叠";变量是持久实体Zasobnik"asNew";只是为Persistable接口设置了标志isNew(由于id生成,这次可能没有必要(。

var number = new Cislo(purpose, remainingRange.getFrom(), false, false, false);
var numberStackRelation = VazbaZasobnikCislo.initialize("CISRAD", stack, number.asNew());
vazbaZasobnikCisloService.save(numberStackRelation.asNew());

VazbaZasobnikCislo.initialize使其他关系保持同步。

private VazbaZasobnikCislo(String autorZmeny, Zasobnik zasobnik, Cislo cislo) {
this.zasobnik = zasobnik;
this.cislo = cislo;
this.auditAttributes = new AuditAttributes(autorZmeny);
}
public static VazbaZasobnikCislo initialize(String autorZmeny, Zasobnik stack, Cislo number) {
var stackNumberRelation = new VazbaZasobnikCislo(autorZmeny, stack, number);
stack.getNumberStackRelations().add(stackNumberRelation);
number.getNumberStackRelations().add(stackNumberRelation);
return stackNumberRelation;
}

以下代码生成此sql:

Hibernate:
insert
into
CISLO
(CERPANO_V_CILOVEM_SYSTEMU_AN, DATUM_ZARAZENI_BLACKLIST, DATUM_ZMENY, HODNOTA_CISLA, NEOPRAVNENE_POUZITI_AN, POUZITE_AN, ID_UCELU)
values
(?, ?, ?, ?, ?, ?, ?) select
scope_identity()
Hibernate:
insert
into
VAZBA_ZASOBNIK_CISLO
(AUTOR_ZMENY, DATUM_ZMENY, ID_CISLA, ID_UZIVATELE_KOMU_PRIDELENO, POPIS, ID_POZADAVKU, ID_UCTU_KOMU_PRIDELENO, ID_ZASOBNIKU)
values
(?, ?, ?, ?, ?, ?, ?, ?) select
scope_identity()
2021-06-10 14:40:23.158  WARN 61377 --- [nio-8087-exec-6] o.h.e.j.s.SqlExceptionHelper             : SQL Error: 547, SQLState: 23000
2021-06-10 14:40:23.161 ERROR 61377 --- [nio-8087-exec-6] o.h.e.j.s.SqlExceptionHelper             : Příkaz INSERT způsobil konflikt s omezením FOREIGN KEY s názvem FK_VAZBA_ZA_R_VAZBA_C_CISLO. Ke konfliktu došlo v databázi CISRAD_KOOP, tabulce dbo.CISLO, , column 'ID_CISLA'.

FK_VAZBA_ZA_R_VAZBA_C_CISLO的定义如下:

更改表格VAZBA_ZASOBNIK_CISLO添加约束FK_VAZBA_ZA_R_VAZBA_C_CISLO外键(ID_CISLA(参考CISLO(ID_CISLA(关于更新级联去

如果你需要更多信息,请告诉我。我将提供捕获的SQL探查器结果,实际发送到数据库的内容。

原来它是一个数据库,而不是插入触发器。

最新更新