Проблема с отношениями ManyToMany в весенних данных. Это изменило мой стол - PullRequest
1 голос
/ 25 апреля 2020

У меня была БД с таблицами SPE C и PARTS. Также у меня была таблица для МНОГООБРАЗНЫХ отношений. В своем проекте я использовал шаблон Spring JDBS, и все работает хорошо. Затем я решаю изменить jdb c на данных SPring jpa. Мои объекты:

  @Entity
@Table(name = "PARTS")
public class PartsJpa {
    @Id
    private int id;
    @Column(name = "NAME")
    private String name;
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "ID_EXPORT", unique = false, nullable = false, updatable = true)
    private ExportJpa exportJpa;
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "ID_TYPE", unique = false, nullable = false, updatable = true)
    private TypesJpa typesJpa;

    @Column(name = "DESCRIPTION")
    private String description;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name="SPEC_PARTS",
            joinColumns = @JoinColumn(name="ID_SPEC", referencedColumnName="id"),
            inverseJoinColumns = @JoinColumn(name="ID_PARTS", referencedColumnName="id")
    )
    private Set<SpecJpa> specJpa;
////////
}

И Spe c:

@Entity
@Table(name = "SPEC")
public class SpecJpa {
    @Id
    private int id;
    @Column(name = "NAME")
    private String name;
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "Creator_ID", unique = false, nullable = false, updatable = true)
    private UsersJpa usersJpa;
    @Column(name = "DESCRIPTION")
    private String description;


    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name="SPEC_PARTS",
            joinColumns = @JoinColumn(name="ID_SPEC", referencedColumnName="id"),
            inverseJoinColumns = @JoinColumn(name="ID_PARTS", referencedColumnName="id")
    )
    private Set<PartsJpa> partsJpa;
////////////////
}

Я не показываю геттеры и сеттеры. Это работает, но когда я запускаю программу, что-то в моей таблице изменилось, и теперь я не могу добавить в таблицу значения spec_parts, такие как (1,3) (1,2). Ошибка: FK_123: PUBLI C .SPEC_PARTS FOREIGN KEY (ID_PARTS) ССЫЛКИ PUBLI C .SPE C (ID) (3) "Нарушение ссылочной целостности:" FK_123: PUBLI C .SPEC_PARTS FOREIGN KEY (ID_PARTS) ССЫЛКИ PUBLI C .SPE C (ID) (3) "; SQL оператор: INSERT INTO" PUBLI C "." SPEC_PARTS "(" ID_SPE C ", "ID_PARTS") VALUES (?,?)

Возможно, у меня ошибка при создании отношений между spe c и деталями? В чем проблема?

data в spe c

ID      NAME    CREATOR_ID      DESCRIPTION     CHANGER_ID  
1       pc            1         description     1
2       pc2           2         description2    2

данные по частям

ID ▼    NAME    ID_EXPORT   ID_TYPE     DESCRIPTION  
1   intel core i5   1        1           d1
2   intel core i7   1        1           d2
3   ddr3            2        2           d3
4   ddr4            2        2           d4
5    asus           3        3           d5

данные в spec_parts сейчас:

ID_SPEC     ID_PARTS  
1           1
2           2

, поэтому я не могу добавить 1,3 или 2,4


Я обнаружил проблему, дата весны что-то изменила и теперь в таблице SPEC_PARTS ID_SPE C отображается на PARTS.ID. Почему?

1 Ответ

2 голосов
/ 25 апреля 2020

Поскольку вы используете отношение ManyToMany, существует созданная таблица сопоставления с именем SPEC_PARTS, в которой есть ссылки на столбцы ID_SPEC и ID_PARTS. Эти значения столбцов получены из SPEC.ID и PARTS.ID. Таким образом, вы не можете вставить в SPEC_PARTS без создания ссылочного значения, потому что вы пытаетесь нарушить ограничение внешнего ключа.

Предположим, есть ли строка в SPEC со значением id 1 и в PARTS есть строка с id значением 2. Затем вы можете вставить в SPEC_PARTS значение (1,2).

Итак, сначала добавьте данные в SPEC и PARTS, а затем сопоставьте их в SPEC_PARTS. И вы можете удалить @JoinTable с одной стороны, вам не нужно определять его с обеих сторон.

Обновление:

Проблема в отношении класса SpecJpa. Здесь вы используете SPEC_PARTS.ID_SPEC в качестве внешнего ключа для PARTS.ID и SPEC_PARTS.ID_PARTS в качестве внешнего ключа для SPEC.ID, что полностью противоположно тому, что вы делаете в классе PartsJpa.

@JoinTable(name="SPEC_PARTS",
            joinColumns = @JoinColumn(name="ID_SPEC", referencedColumnName="id"),
            inverseJoinColumns = @JoinColumn(name="ID_PARTS", referencedColumnName="id")
    )

Вот почему эта ошибка говорит

SPEC_PARTS FOREIGN KEY(ID_PARTS) REFERENCES PUBLIC.SPEC(ID) (3)";

В базе данных нет SPEC.ID значения 3.

Решение: Удалить @JoinTable из SpecJpa класс, так как вам не нужно указывать обе стороны. И также удалите неправильное отношение внешнего ключа из базы данных.

...