Refactoring JPA Links

I am refactoring some classes from standard SQL to JPA / ORM. In most cases, objects have a "real" reference, but sometimes other objects are referenced only by reference to an uncontrolled database ID (no foreign key, just a simple string with a reference to another table ID).

The code looks like this:

@Entity
public final class myEntity implements Serializable {
    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    @Column(name = "ID")
    private String id;

    @OneToOne
    @JoinColumn(name = "OBJREF", nullable = false)
    private otherObject objReference; /* Nice object reference */

    @Column(name = "OTHEROBJREF")
    private String otherObjReference; /* Damn db reference used by legacy code */
}

      

How do I work with otherObjReference? The attribute is used by legacy systems that need a static getter / setter construct using String! If I stay with the ID, I have problems with JPA requests and I can't just assign the entity and save it.

I thought about converting the String and working with @PrePersist and @PreLoad to load the "real" object reference so that I can work with both. But in these methods, I don't have access to the EntityManager (and persistence shouldn't be that pojo's job in this case ... it smells like bad design if I load the links here).

Since "otherObjReference" is private, I can also use getters and setters to load data from my real reference. But other layers work with objects, so they fail when they call getOtherObjReference () method because they don't have a db connection to load the object.

+2


source to share


2 answers


It is also possible (at least with the basic principles of binding) to map the same column with two fields, as long as only one can be updateable and insertable.

@Column(name = "OBJREF", nullable = false)
private String otherObjectId;

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "OBJREF", nullable=false, updatable=false, insertable=false)
private OtherObject otherObject;

      



In your method, setOtherObject

you can also set otherObjectId

. The only problem with this approach is that if you only set the String field, the object will only update after saving and reloading the object from the db.

+2


source


Have you really tried your last solution?

those. do a normal JPA mapping and then force the getter to return an id like this?

public ID getOtherObjId() {
  return otherObj.getId();
}

      



In fact, there is a good chance it will work even after you leave the session boundaries. I'm not sure how it works today, but at least on some older version of hibernation, it would put a lazy proxy in the otherObj reference when it loaded your entity, and that lazy proxy would contain the id of the referenced object. So when you only access the id from otherObj, it is smart enough not to load the object.

If that doesn't work, you can always force the Ref. It's a little expensive, but it might cost you.

(BTW, if you use @OneToOne and nullable = true it will always load the other side eagerly. See here (find 'one-to-one') for some quick explanation)

+1


source







All Articles