I have a situation where I need to join tables on an object in an ORM class hierarchy where the join column is NOT the primary key of the base class. Here is an example of
I was able to find a solution to this. If you map the Bar class like so
@Entity
@DiscriminatorValue("1")
@SecondaryTable(name = "BAR", pkJoinColumns = { @PrimaryKeyJoinColumn(name = "FOO_ID", referencedColumnName = "FOO_ID") })
public class Bar extends Foo {
@OneToOne
@JoinColumn(table = "BAR", name = "BAR_ID")
MiniBar miniBar;
}
and add the following class
@Entity
@SqlResultSetMapping(name = "compositekey", entities = @EntityResult(entityClass = MiniBar.class, fields = { @FieldResult(name = "miniBar", column = "BAR_ID"), }))
@NamedNativeQuery(name = "compositekey", query = "select BAR_ID from BAR", resultSetMapping = "compositekey")
@Table(name = "BAR")
public class MiniBar {
@Id
@Column(name = "BAR_ID")
Long barId;
}
You can then add any sort of mapping you want to the MiniBar
class as if barId were the primary key, and then further make it available in the outer Bar
class.
You will not be able to do what you want. @CollectionOfElements (and @OneToMany, for that matter) are always mapped via owner's entity primary key.
The way you map Foo / Bar inheritance is rather strange as well - they clearly are not in the same table; seems like using JoinedSubclass would be a better approach. Keep in mind that still won't help you map bar_names
to bar_id
because primary key value is shared among the hierarchy (even though column name may be different for subclass).
A possible alternative is to use @OneToOne mapping between Foo and Bar instead of inheritance. That's the only way you will be able to map bar_names
to bar_id
and the most appropriate mapping for you table structure (though, perhaps, not for your domain model).
Not sure how to do this with JPA/Annotations, but with Hibernate XML mapping files it would be something like:
<class name="Bar" table="BAR">
<id name="id" type="int">
<column name="BAR_ID"/>
<generator class="native"/>
</id>
<set name="barNames" table="BAR_NAMES">
<!-- Key in BAR_NAMES table to map to this class's key -->
<key column="BAR_ID"/>
<!-- The value in the BAR_NAMES table we want to populate this set with -->
<element type="string" column="BAR_NAME"/>
</set>
</class>