Как сохранить родительско-дочерние объекты с отображением @OneToOne и последовательностью, созданной на основе первичного ключа - PullRequest
0 голосов
/ 19 сентября 2019

Я никуда не денусь, потратив на это часы.Я не могу обойти эту ошибку из базы данных:

org.postgresql.util.PSQLException: ERROR: insert or update on table "receiver_params" violates foreign key constraint "fkoo8xfchpie8h1lock8ish68a7"
  Detail: Key (id)=(46) is not present in table "partner".

Попытка:

Я пытаюсь сохранить партнера следующим образом:

Partner partner = new Partner();
ReceiverParams params = new ReceiverParams();
partner.setReceiverParams(params);
partnerDao.save(partner);

Код:

Вот соответствующие биты классов сущностей:

@Entity
public class Partner {
    @Id
    @SequenceGenerator(allocationSize= 1, name = "catalogGen", sequenceName = "catalogCounter")
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "catalogGen")
    @Column(name = "id")
    private Long id;

    @OneToOne(mappedBy="partner", cascade = CascadeType.ALL)
    private ReceiverParams receiverParams;
}

@Entity
public class ReceiverParams {
    @Id
    @SequenceGenerator(allocationSize= 1, name = "catalogGen", sequenceName = "catalogCounter")
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "catalogGen")
    @Column(name = "id")
    private Long id;

    @PrimaryKeyJoinColumn
    @OneToOne(cascade = CascadeType.ALL, optional = false, orphanRemoval = true)
    private Partner partner;
}

И таблица DDL:

-- Table: partner
CREATE TABLE partner
(
    id bigint NOT NULL,
    CONSTRAINT partner_pkey PRIMARY KEY (id),
    CONSTRAINT fko7mdrugj20xnulw9nph9hw34x FOREIGN KEY (sender_config_id)
        REFERENCES config (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION,
    CONSTRAINT fksypxt08sx9qj5vma73dvlawoa FOREIGN KEY (receiver_config_id)
        REFERENCES config (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;


-- Table: receiver_params
CREATE TABLE receiver_params
(
    id bigint NOT NULL,
    CONSTRAINT receiver_params_pkey PRIMARY KEY (id),
    CONSTRAINT fkoo8xfchpie8h1lock8ish68a7 FOREIGN KEY (id)
        REFERENCES partner (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;

Я попытался сохранить «партнер», затем добавить «параметры», сначала сохранить параметры, затем «партнер».Но я не могу понять, как сохранить партнера с помощью связанных параметров.

Читая другой код, я почти уверен, что аннотации к модельным классам верны.SQL был сгенерирован автоматически.Что мне не хватает?

Заранее спасибо

Редактировать

FWIW, это мой PartnerDao:

public interface PartnerDao extends JpaRepository<Partner, Long> {
}

Ответы [ 2 ]

0 голосов
/ 19 сентября 2019

Проблема заключалась в том, что мой класс ReceiverParams генерировал новый идентификатор вместо использования стратегии внешнего ключа для использования идентификатора в связанном классе Partner.

Вот часть, которая изменилась на ReceiverParams.В частности, аннотация @GenericGenerator со стратегией foreign, примененной к свойству partner.

@Entity
public class ReceiverParams {

    @Id
    @GenericGenerator(name = "receiverGen", strategy = "foreign", parameters = { @Parameter(name = "property", value = "partner") })
    @GeneratedValue(generator = "receiverGen")
    @Column(name = "id")
    private Long id;

// ... the rest was unchanged in all remaining files

}
0 голосов
/ 19 сентября 2019

У вас двунаправленное высвобождение, и я думаю, что вы неправильно настраиваете его обе стороны.

Попробуйте это:

Partner partner = new Partner();
ReceiverParams params = new ReceiverParams();

partner.setReceiverParams(params);
params.setPartner(partner);

partnerDao.save(partner);

Более элегантный способ достижения того же результата с модификациейsetReceiverParams метод:

public void setReceiverParams(ReceiverParams params) {
     params.setPartner(this);
     this.params = params;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...