views:

249

answers:

3

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 Hibernate's back" and sneak values into that field without having to drop down to JDBC or implement an interceptor?

Thanks!

A: 

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.

royal
Using mappedBy is the JPA equivalent to inverse=true.
Alex Cruise
+1  A: 

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);
}
Willi
A: 

hailo im facing the same problem. my column with insertable=false doent get updated..

could u pls tell me how u got it solved !!!!!!!!!!

i've been struggling for days :(

sammy
Hi Sammy, 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.
Alex Cruise