Hibernate много к одному внешнему ключу не устанавливается - PullRequest
0 голосов
/ 08 января 2012

У меня довольно прямое отношение «один ко многим»

[SampleAliasMask] has many [SampleAliasMaskPart]

Моя проблема в : при сохранении нового экземпляра SampleAliasMask с частями коллекции я получаю нарушение ограничения, котороессылка внешнего ключа из таблиц SampleAliasMaskPart на SampleAliasMask установлена ​​в NULL.

Я сопоставляю, используя аннотации гибернации как таковые:

@Entity
@Table(name="SAMPLE_ALIAS_MASK")
public class SampleAliasMask extends ClientEntity {
    @OneToMany(mappedBy = "sampleAliasMask", fetch = FetchType.EAGER, cascade = javax.persistence.CascadeType.ALL, orphanRemoval = true)
    @Cascade(CascadeType.ALL)
    @Length(min = 1, message = "The sample alias mask must have components")
    private Set<SampleAliasMaskPart> components;

С другой половиной отношения, сопоставленной какИтак:

@Entity
@Table(name="SAMPLE_ALIAS_MASK_PART")
public class SampleAliasMaskPart extends ClientEntity {
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "SAMPLE_ALIAS_MASK_ID", nullable = false)
    private SampleAliasMask sampleAliasMask;

Соответствующей частью ClientEntity является

@MappedSuperclass
public abstract class ClientEntity {
    @Id
    @Column(name="ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

Я создаю такие детали:

HashSet<SampleAliasMaskPart> components = new HashSet<>();
for(Map<String, Object> c : this.components) {
    SampleAliasMaskPart component = new SampleAliasMaskPart(Integer.parseInt(c.get("value").toString(), 10), c.get("name").toString());
    result.validate(component);
    components.add(component);
}
mask.setComponents(components);

Точная ошибка, которую я получаю:

java.sql.BatchUpdateException: ORA-01400: cannot insert NULL into ("ST"."SAMPLE_ALIAS_MASK_PART"."SAMPLE_ALIAS_MASK_ID")

Я подозреваю, что проблема связана с тем фактом, что я никогда не устанавливал явно SampleAliasMaskPart.sampleAliasMask, но зачем мне это нужно?Эти отношения никогда не подвергаются и не подвергаются воздействию.Это поле предназначено только для целей отображения, что заставляет меня думать, что я отображаю это неправильно.

Ответы [ 2 ]

1 голос
/ 08 января 2012

Ваше предположение верно.Hibernate использует собственную сторону ассоциации, чтобы знать, существует ассоциация или нет.А сторона-владелец - сторона, где нет атрибута mappedBy.

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

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

0 голосов
/ 09 января 2012

Дж. Б. Низет предложил правильно. Вы можете решить эту проблему двумя способами:

  1. Удаление двунаправленной взаимосвязи: удалите аннотацию @ManyToOne(optional = false, fetch = FetchType.LAZY) из simpleAliasMask in SampleAliasMaskPart

  2. Добавьте mask к каждому component, выполнив что-то вроде component.setSimpleAliasMask(mask). Это сделает двусторонние отношения.

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