Переход за спину Hibernate для обновления значений внешнего ключа без связанной сущности - PullRequest
1 голос
/ 27 февраля 2010

Обновлено : Я решил "решить" проблему, выполнив противоположное действие! Теперь у меня есть поле ссылки на сущность, доступное только для чтения (inserttable = false, Updatable = false), и поле внешнего ключа для чтения-записи. Это означает, что мне нужно проявлять особую осторожность при сохранении новых сущностей, но при запросах свойства сущностей разрешаются для меня.


У меня двунаправленная ассоциация «один ко многим» в моей доменной модели, где я использую аннотации JPA и Hibernate в качестве поставщика сохраняемости. Это в значительной степени ваша стандартная родительская / дочерняя конфигурация, с одним отличием в том, что я хочу представить внешний ключ родителя как отдельное свойство дочернего элемента вместе со ссылкой на родительский экземпляр, например:

@Entity
public class Child {
    @Id @GeneratedValue
    Long id;

    @Column(name="parent_id", insertable=false, updatable=false)
    private Long parentId;

    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="parent_id")
    private Parent parent;

    private long timestamp;
}

@Entity
public class Parent {
    @Id @GeneratedValue
    Long id;

    @OrderBy("timestamp")
    @OneToMany(mappedBy="parent", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    private List<Child> children;
}

В большинстве случаев это работает нормально, но во многих (устаревших) случаях я хотел бы поместить недопустимое значение в столбец parent_id, не создавая сначала фиктивного Parent.

К сожалению, Hibernate не будет сохранять значения, присвоенные полю parentId из-за insertable=false, updatable=false, что требуется, когда один и тот же столбец сопоставлен с несколькими свойствами. Есть ли какой-нибудь хороший способ «пойти за спину Hibernate» и вставить значения в это поле без необходимости переходить в JDBC или реализовывать перехватчик?

Спасибо!

Ответы [ 2 ]

1 голос
/ 27 февраля 2010

Что плохого в фиктивном Родителе?Есть аккуратный способ сделать это в одном месте:

public void setParent(Parent parent) {
    this.parent = parent;
    this.parentId = parent == null ? null : parent.getId();
}

public void setParentId(Long parentId) {
    final Parent parent;
    if (parentId == null) {
        parent = null;
    } else {
        parent = new Parent();
        parent.setId(parentId);
    }
    setParent(parent);
}
0 голосов
/ 27 февраля 2010

Вы смотрели на установку ManyToOne на child inverse = true вместо того, чтобы сказать, что значение свойства нельзя вставлять / обновлять? Если inverse = true делает то, что раньше, он сделает сущность Child «не источником истины» для отношений. Он все равно будет читать столбец, но не будет писать это. Я думаю. Я давно не был в такой ситуации.

...