Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[eclipselink-users] Thorny JPA @OneToMany + @Generated + @EmbeddedId question

My apologies if there is a better place to ask this; I figured that since this will be the JPA 2.0 reference implementation I'd start here.

I have a Person object that I'd like to link with a Map of Addresses, indexed by a String type.  I'd also like to allow a given Address to be shared between Persons.

That suggests that an Address should have an owner Person, and a type field, and that the conjunction of the type and the owner's ID should form its primary key.

So:

Person
------
personID (PK; auto generated)
various other fields

Address
-------
personID (1/2 of PK and FK to Person.personID)
type (other 1/2 of PK)
various other fields

These would be represented by relationships like this:

(in Person.java:)
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long personID;

@OneToMany(mappedBy = "owner")
private Map<AddressPK, Address> addresses;

(in Address.java:)
@EmbeddedId
private PK pk;

@ManyToOne
@JoinColumn(name = "personID")
private Person owner;

@Embeddable
public static class PK implements Serializable {
  @Column(name = "type")
  String type;
  @Column(name = "personID")
  long personID;
}

If I create a new Person, add an Address to him under a given type, and then ask an EntityManager to persist the Person graph--and if I've annotated the Address relationship to cascade, of course--then I'd want the graph to persist.  But at the moment, it doesn't do that, and I don't see an obvious way to enable this relatively common use case to happen.

If I try to persist the graph, then when it comes time to persist the dependent object (the Address) it does not have enough information to fill in the Address#pk#personID field, because at insert time it does not have a PK (since it's generated by the database).  Consequently, EclipseLink (and Hibernate, and OpenJPA) try to insert NULL for the personID column in the Address table, which fails, correctly.

What I'd like to have happen is two things, really:
  • I'd like to use the owner property (the @ManyToOne relationship) as 1/2 of a primary key for the Address entity, and its type field for the other half.
  • I'd like the ORM tool to somehow use the generated Person ID when inserting the Address entity instead of NULL.
What's the expected behavior here, and/or what's the appropriate recipe to accomplish this?

I'm happy to clarify if anything in here is confusing.

Best,
Laird

Back to the top