Насколько я могу судить, нарушение постороннего ключа в postgres не должно происходить.(с гибернацией) - PullRequest
1 голос
/ 31 марта 2011

Итак, у меня есть две таблицы:

table A
-id
-other stuff

table B
-id
-stuff
-a_id, a fk column to id in A

в спящем режиме, я отобразил B.a_id как простое свойство (я не хочу много-к-одному и получаю целый экземпляр AЯ просто хочу Id).Допустим, у меня есть строка в A с id = 100.

, если я пытаюсь вставить новую строку в B, с a_id = 100, я получаю нарушение ограничения внешнего ключа postgres, говорящее, что A не существует с id= 100!

Я этого не понимаю.Я включил show_sql в hibernate, и он генерирует это для вставки B:

insert into B (stuff, a_id) values (?, ?)

, чтобы это выглядело корректно.

Отображение гибернации, которое у меня есть для B.a_id, выглядит так:

   <property name="aId" type="java.lang.Long" unique="true" not-null="true">
        <column name="a_id" />
    </property>

ограничение, добавленное в postgres, выглядит следующим образом:

alter table B 
add constraint myfk
foreign key (a_id) 
references A;

Есть идеи?
Спасибо

edit: Я не думаю, что hibernate имеет какое-либо отношениес этим.если я пытаюсь вставить вручную с помощью sql, я получаю ту же ошибку.

edit2: есть тонкий поворот - поля id являются int8 и имеют последовательности на них:

    create table A (
id int8 not null unique,
stuff varchar(10),
primary key(id)
);
create table B (
id int8 not null unique,
a_id int8 not null references A,
primary key(id)
);

create sequence a_seq;
ALTER SEQUENCE a_seq OWNED BY a.id;
ALTER TABLE a ALTER COLUMN id SET DEFAULT nextval('a_seq');

create sequence b_seq;
ALTER SEQUENCE b_seq OWNED BY b.id;
ALTER TABLE b ALTER COLUMN id SET DEFAULT nextval('b_seq');

Ответы [ 2 ]

1 голос
/ 31 марта 2011

Если есть родительская строка в таблице A, PostgreSQL не выдаст ошибку.

Генерация столбцов идентификаторов также не должна иметь значения (после вставки родительской строки).

Единственное, о чем я могу подумать: возможно, вы вставили строку в таблицу A в другой сеанс гибернации и забыли зафиксировать это?

Другая сессия / транзакция, которая вставляет строку в таблицу B, не увидит незафиксированную строку в таблице A.

У меня нет проблем с непосредственным выполнением операторов:

postgres=> create table A (
postgres(>   id int8 not null unique,
postgres(>   stuff varchar(10),
postgres(>   primary key(id)
postgres(> );
CREATE TABLE
postgres=>
postgres=> create table B (
postgres(>   id int8 not null unique,
postgres(>   a_id int8 not null references A,
postgres(>   stuff varchar(10),
postgres(>   primary key(id)
postgres(> );
CREATE TABLE
postgres=>
postgres=> create sequence a_seq;
CREATE SEQUENCE
postgres=> ALTER SEQUENCE a_seq OWNED BY a.id;
ALTER SEQUENCE
postgres=> ALTER TABLE a ALTER COLUMN id SET DEFAULT nextval('a_seq');
ALTER TABLE
postgres=>
postgres=> create sequence b_seq;
CREATE SEQUENCE
postgres=> ALTER SEQUENCE b_seq OWNED BY b.id;
ALTER SEQUENCE
postgres=> ALTER TABLE b ALTER COLUMN id SET DEFAULT nextval('b_seq');
ALTER TABLE
postgres=>
postgres=> COMMIT;
COMMIT
postgres=> INSERT INTO a (stuff) VALUES ('a_stuff');
INSERT 0 1
postgres=> commit;
COMMIT
postgres=> select * from a;
 id |  stuff
----+---------
  1 | a_stuff
(1 row)


postgres=> INSERT INTO b (a_id, stuff) VALUES (1, 'b_stuff');
INSERT 0 1
postgres=> commit;
COMMIT;
postgres=>
1 голос
/ 31 марта 2011
CREATE TABLE A (id INT, other_stuff VARCHAR(20) NULL);
CREATE TABLE b (id INT, stuff VARCHAR(20) NULL, a_id INT);
ALTER TABLE A ADD CONSTRAINT PK_A PRIMARY KEY (id);
ALTER TABLE B ADD CONSTRAINT myfk FOREIGN KEY (a_id) REFERENCES A;

INSERT INTO A (id) VALUES (100);
INSERT INTO B (id, a_id) VALUES (1,100);

SELECT * FROM a JOIN b ON a.id = b.a_id;
 id  | other_stuff | id | stuff | a_id 
-----+-------------+----+-------+------
 100 |             |  1 |       |  100

Я попытался продублировать вашу проблему, используя приведенный выше SQL в PostgreSQL 9.0.3, и не смог продублировать вашу ошибку.Любой DDL / DML, который вы можете захватить, а также точное сообщение об ошибке, будет полезно.

(я буду продолжать добавлять информацию, когда вы будете предоставлять дополнительную информацию. Надеюсь, это может послужить отправной точкой и для кого-то еще.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...