Избегайте вставки дочерней строки, если она существует в MySQL с Hibernate - PullRequest
0 голосов
/ 12 февраля 2020

В моем приложении есть форма, для которой данные хранятся с использованием Hibernate. Форма является дочерней по отношению к родителю, и у них есть OneToOne отображение, что означает, что только один дочерний элемент должен быть вставлен / доступен в дочернюю таблицу (например, MIQ) для родительской записи (например, Card).

Однако, учитывая сценарий, когда несколько пользователей пытаются заполнить форму для одной и той же родительской записи в одно и то же время и когда она сохраняется обоими пользователями, гибернация заканчивает тем, что сохраняет две строки в дочерней таблице, в которой должен быть один .

Есть ли способ контролировать это поведение и не вставлять дочернюю строку, если она есть против родительской записи. Можно ли им управлять с помощью механизма блокировки?

Ниже приведен POJO обеих сущностей. Я использую Spring Data JPA для сохранения сущности.

Дочерняя сущность

@Data
@NoArgsConstructor
@EqualsAndHashCode(exclude = {}, callSuper = true)
@ToString(exclude = {})
@Entity
@DynamicUpdate
@Table(name = "miq")
public class MIQ extends GenericTableConstants {

    @Column(name = "entity_name")
    private String entityName;

    @Column(name = "entity_branch")
    private String entityBranch;

    @Column(name = "product")
    private String product;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="card_id", referencedColumnName = "id")
    private Card card;
}

Родительская сущность

@Data
@NoArgsConstructor
@EqualsAndHashCode(exclude = {}, callSuper = true)
@ToString(exclude = {})
@Entity
@DynamicUpdate
@Table(name = "card")
public class Card extends GenericTableConstants {

    @NotEmpty(message = "{NotEmpty.card.title}")
    @Column(name = "title", length = 500, nullable = false)
    private String title;

    @Column(name = "description", columnDefinition = "LONGTEXT") // columnDefinition makes the column type to LONG TEXT
    private String description;

    @Column(name = "entity_id")
    private Integer entityId;

    @Column(name = "priority")
    private String priority;

    @Column(name="is_archived", nullable = false, columnDefinition = "char default 'N'")
    @Type(type = "org.hibernate.type.YesNoType")
    private Boolean isArchived = false;

    @Column(name = "due_date")
    private LocalDateTime dueDate;

    @JsonIgnoreProperties(value = {"card"}, allowSetters = true)
    @OneToOne(fetch = FetchType.LAZY, targetEntity = MIQ.class, mappedBy = "card")
    private MIQ miq;
}
...