开发者

Going "behind Hibernate's back" to update foreign key values without an associated entity

Updated: I wound up "solving" the problem by doing the opposite! I now have the entity reference field set as read-only (insertable=false updatable=false), and the foreign key field read-write. This means I need to take special care when saving new entities, but on querying, the entity properties get resolved for me.


I have a bidirectional one-to-many association in my domain model, where I'm using JPA annotations and Hibernate as the persistence provider. It's pretty much your bog-standard parent/child configuration, with one difference being that I want to expose the parent's foreign key as a separate property of the child alongside the reference to a parent instance, like so:

@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;
}

This works just fine most of the time, but there are many (legacy) cases when I'd like to put an invalid value in the parent_id column without having to create a bogus Parent first.

Unfortunately, Hibernate won't save values assigned to the parentId field due to insertable=false, updatable=false, which it requires when the same column is mapped to multiple properties. Is there any nice way to "go behind开发者_如何学Python Hibernate's back" and sneak values into that field without having to drop down to JDBC or implement an interceptor?

Thanks!


Whats wrong about a bogus Parent? There is a neat way to do it in one place:

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);
}


Have you looked into setting the ManyToOne on the child inverse=true, instead of telling the property value to be un-insertable/updatable? If the inverse=true does what it used to, it'll make the Child entity "not the source of truth" for the relationship.. It'll still read the column, but not write it.. I think. It's been a while since I've been in this situation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜