@OneToMany отношения с композитным ключом - PullRequest
0 голосов
/ 06 февраля 2012

У меня есть следующая модель (игнорируя неактуальный / очевидный код, такой как сеттеры и геттеры):

@Entity
public class Invoice {
    @Id // sequence generated
    private Long invoiceId;

    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(name = "invoiceId", referencedColumnName = "invoiceId")
    @OrderBy("id.itemNumber")
    List<Item> items = new ArrayList<Item>();
}


@Entity
public class Item {
    @EmbeddedId
    private ItemPK id;
}


@Embeddable
public class ItemPK {
    private Long invoiceId;
    private Long itemNumber;
}

Невозможно изменить структуру БД, так как это устаревшая БД: (

ItemNumber, по сути, является индексом, который начинается с нуля.

Если я возьму существующий счет-фактуру и просто удалю существующий элемент и добавлю 2 новых элемента в список, при попытке обновить объект счета-фактуры я запускаю всевиды проблем:

Если я оставлю ItemPK пустым, я получу: org.hibernate.TransientObjectException: объект является несохраненным временным экземпляром - сохраните временный экземпляр перед объединением

Если я попытаюсь заполнить значения ItemPK самостоятельно (идентификатор счета и индекса), я получу: org.hibernate.NonUniqueObjectException: другой объект с тем же идентификаторомзначение уже было связано с сеансом (в БД уже есть элемент счета-фактуры, и он имеет идентификатор счета-фактуры и индекс = 0, как и первый объект в моем новомсписок элементов).

Если я попытаюсь оставить invoiceId пустым (в объекте ItemPK), я получу: java.sql.BatchUpdateException: ORA-01400: невозможно вставить NULL в ("Item". "InvoiceId")

Есть ли способ разрешить Hibernate / JPA это?Или мне нужно полностью удалить связь, определить список как @Transient и просто заполнить его и сохранить в моих классах обслуживания?

Спасибо.

1 Ответ

1 голос
/ 06 февраля 2012

У вас фактически есть двунаправленная связь, поскольку invoiceId в сущности Item на самом деле является внешним ключом для Invoice. Таким образом, вы должны сопоставить ассоциацию как двунаправленную и использовать аннотацию @MapsId. У его Javadoc есть пример.

...