Anonymous
Транзакции в IBM I (AS400) и Spring Boot 3
Сообщение
Anonymous » 14 ноя 2024, 22:22
Откат транзакции у меня не работает, я работаю на IBM I (AS400), и среди тестов, которые я выполняю, откат у меня не сработал, я генерирую намеренную ошибку, дублируя идентификаторы в вот так:
Код: Выделить всё
{
"id": 24,
"name": "Test Activity",
"module": {
"id": 2
},
"submodule": {
"moduleId": 2,
"submoduleId": 2
},
"user": {
"id": "luipena"
},
"admin": {
"id": "luipena"
},
"descrip": "First test having text in all possible fields",
"area": {
"id": 1
},
"main_request_type": {
"id": 1
},
"main_consecutive": 5487965,
"start_date": "2024-10-10",
"finish_date": "2024-10-10",
"status": {
"id": 1
},
"current": "Y",
"subactivities": [
{
"id": 7,
"subactivity": {
"id": 1
},
"user": {
"id": "luipena"
},
"start_date": "2024-10-10",
"finish_date": "2024-10-10",
"progress": 0
}
]
}
Это моя основная сущность:
Код: Выделить всё
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = GlobalVariables.activityTable, schema = GlobalVariables.schemaMain)
public class Activity {
@Id
@Column(name = "ID")
private Integer id;
@Column(name = "TITLE")
private String name;
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH })
@JoinColumn(name = "ID_MOD", insertable = false, updatable = false)
private Module module;
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH })
@JoinColumns({
@JoinColumn(name = "ID_MOD"),
@JoinColumn(name = "ID_SUBMOD")
})
private Submodule submodule;
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH })
@JoinColumn(name = "ID_USER")
private User user;
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH })
@JoinColumn(name = "ID_ADMIN")
private User admin;
@Column(name = "DESCRIP")
private String descrip;
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH })
@JoinColumn(name = "ID_AREA")
private Area area;
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH })
@JoinColumn(name = "FTYPE")
private RequestType main_request_type;
@Column(name = "F_CONS", columnDefinition = "bigint")
private Long main_consecutive;
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH })
@JoinColumn(name = "STYPE")
private RequestType secondary_request_type;
@Column(name = "S_CONS", columnDefinition = "bigint")
private Long secondary_consecutive;
@Column(name = "START")
private LocalDate start_date;
@Column(name = "FINISH")
private LocalDate finish_date;
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH })
@JoinColumn(name = "ID_STATUS")
private Status status;
@Column(name = "UP_TO_DATE", columnDefinition = "char")
private String current;
@ToString.Exclude
@OneToMany(mappedBy = "activity", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set subactivities;
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o))
return false;
Activity activity = (Activity) o;
return id != null && Objects.equals(id, activity.id);
}
@Override
public int hashCode() {
return getClass().hashCode();
}
}
Это моя дополнительная сущность:
Код: Выделить всё
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Entity
@Table(name = GlobalVariables.subactivityOfActivityTable, schema = GlobalVariables.schemaMain)
public class SubactivityOfActivity {
@Id
@Column(name = "ID", columnDefinition = "bigint")
private Long id;
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH })
@JoinColumn(name = "ID_ACTIVID")
private Activity activity;
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH })
@JoinColumn(name = "ID_SUBACT")
private Subactivity subactivity;
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH } )
@JoinColumn(name = "ID_USER")
private User user;
@Column(name = "START")
private LocalDate start_date;
@Column(name = "FINISH")
private LocalDate finish_date;
@Column(name = "PROGRESS", columnDefinition = "smallint")
private Short progress;
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o))
return false;
SubactivityOfActivity subactivityOfActivity = (SubactivityOfActivity) o;
return id != null && Objects.equals(id, subactivityOfActivity.id);
}
@Override
public int hashCode() {
return getClass().hashCode();
}
}
Мой реализованный сервис:
Код: Выделить всё
@Override
@Transactional
public void save(Activity activity) {
activityRepository.saveActivity(activity);
}
Мой репозиторий:
Код: Выделить всё
@Override
public void saveActivity(Activity activity) {
em.persist(activity);
em.flush();
}
Дублируется идентификатор поддействия, но не само действие. Предполагается, что в транзакции делается все или ничего не делается, но при этом активность сохраняется, поддеятельность выдает повторяющуюся ошибку, а активность записывается в базу данных, чего быть не должно
Я уже пробовал несколько вещей, и я воспроизвел свой пример в PostgreSQL, и там я вижу откат, отраженный в журнале, и база данных работает, когда я делаю это здесь, в IBM I (AS400) , откат не работает
Пояснение: я использую Spring Boot 3.3.5, JPA и подключаюсь к IBM, используя его драйвер JTOpen 20.0.7
Подробнее здесь:
https://stackoverflow.com/questions/791 ... ing-boot-3
1731612141
Anonymous
Откат транзакции у меня не работает, я работаю на IBM I (AS400), и среди тестов, которые я выполняю, откат у меня не сработал, я генерирую намеренную ошибку, дублируя идентификаторы в вот так: [code]{ "id": 24, "name": "Test Activity", "module": { "id": 2 }, "submodule": { "moduleId": 2, "submoduleId": 2 }, "user": { "id": "luipena" }, "admin": { "id": "luipena" }, "descrip": "First test having text in all possible fields", "area": { "id": 1 }, "main_request_type": { "id": 1 }, "main_consecutive": 5487965, "start_date": "2024-10-10", "finish_date": "2024-10-10", "status": { "id": 1 }, "current": "Y", "subactivities": [ { "id": 7, "subactivity": { "id": 1 }, "user": { "id": "luipena" }, "start_date": "2024-10-10", "finish_date": "2024-10-10", "progress": 0 } ] } [/code] Это моя основная сущность: [code]@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Entity @Table(name = GlobalVariables.activityTable, schema = GlobalVariables.schemaMain) public class Activity { @Id @Column(name = "ID") private Integer id; @Column(name = "TITLE") private String name; @ToString.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH }) @JoinColumn(name = "ID_MOD", insertable = false, updatable = false) private Module module; @ToString.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH }) @JoinColumns({ @JoinColumn(name = "ID_MOD"), @JoinColumn(name = "ID_SUBMOD") }) private Submodule submodule; @ToString.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH }) @JoinColumn(name = "ID_USER") private User user; @ToString.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH }) @JoinColumn(name = "ID_ADMIN") private User admin; @Column(name = "DESCRIP") private String descrip; @ToString.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH }) @JoinColumn(name = "ID_AREA") private Area area; @ToString.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH }) @JoinColumn(name = "FTYPE") private RequestType main_request_type; @Column(name = "F_CONS", columnDefinition = "bigint") private Long main_consecutive; @ToString.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH }) @JoinColumn(name = "STYPE") private RequestType secondary_request_type; @Column(name = "S_CONS", columnDefinition = "bigint") private Long secondary_consecutive; @Column(name = "START") private LocalDate start_date; @Column(name = "FINISH") private LocalDate finish_date; @ToString.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH }) @JoinColumn(name = "ID_STATUS") private Status status; @Column(name = "UP_TO_DATE", columnDefinition = "char") private String current; @ToString.Exclude @OneToMany(mappedBy = "activity", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private Set subactivities; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; Activity activity = (Activity) o; return id != null && Objects.equals(id, activity.id); } @Override public int hashCode() { return getClass().hashCode(); } } [/code] Это моя дополнительная сущность: [code]@Getter @Setter @NoArgsConstructor @AllArgsConstructor @ToString @Entity @Table(name = GlobalVariables.subactivityOfActivityTable, schema = GlobalVariables.schemaMain) public class SubactivityOfActivity { @Id @Column(name = "ID", columnDefinition = "bigint") private Long id; @ToString.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH }) @JoinColumn(name = "ID_ACTIVID") private Activity activity; @ToString.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH }) @JoinColumn(name = "ID_SUBACT") private Subactivity subactivity; @ToString.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.DETACH, CascadeType.REFRESH } ) @JoinColumn(name = "ID_USER") private User user; @Column(name = "START") private LocalDate start_date; @Column(name = "FINISH") private LocalDate finish_date; @Column(name = "PROGRESS", columnDefinition = "smallint") private Short progress; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; SubactivityOfActivity subactivityOfActivity = (SubactivityOfActivity) o; return id != null && Objects.equals(id, subactivityOfActivity.id); } @Override public int hashCode() { return getClass().hashCode(); } } [/code] Мой реализованный сервис: [code]@Override @Transactional public void save(Activity activity) { activityRepository.saveActivity(activity); } [/code] Мой репозиторий: [code]@Override public void saveActivity(Activity activity) { em.persist(activity); em.flush(); } [/code] Дублируется идентификатор поддействия, но не само действие. Предполагается, что в транзакции делается все или ничего не делается, но при этом активность сохраняется, поддеятельность выдает повторяющуюся ошибку, а активность записывается в базу данных, чего быть не должно Я уже пробовал несколько вещей, и я воспроизвел свой пример в PostgreSQL, и там я вижу откат, отраженный в журнале, и база данных работает, когда я делаю это здесь, в IBM I (AS400) , откат не работает Пояснение: я использую Spring Boot 3.3.5, JPA и подключаюсь к IBM, используя его драйвер JTOpen 20.0.7 Подробнее здесь: [url]https://stackoverflow.com/questions/79190069/transactions-on-ibm-i-as400-and-spring-boot-3[/url]