Two tables like:
CREATE TABLE foo (
id INT PRIMARY KEY,
x TEXT
);
CREATE TABLE bar (
foo_id INT REFERENCES foo (id) ON DELETE CASCADE,
y TEXT,
z TEXT
);
...can be mapped like so:
@Table(name = "foo")
@SecondaryTable(name = "bar", pkJoinColumns = @PrimaryKeyJoinColumn(name = "foo_id", referencedColumnName = "id"))
class Foo {
@Id
int id;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "y", column = @Column(table = "bar")),
@AttributeOverride(name = "z", column = @Column(table = "bar"))
})
Bar bar;
}
@Embeddable
class Bar {
String y;
String z;
}
Is there a less awkward way to do this mapping, using either just standard JPA annotations, or else Hibernate-specific annotations (and without introducing a parent reference in the embeddable object)?
Compare this to how easily a collection of @Embeddable
objects can be referenced using an @ElementCollection
and @CollectionTable
.
Sorry for the late answer, but the question interested me so I figured I'd take a crack at it.
A more elegant solution is to make the contents of bar
an Entity instead of an Embeddable, and to use a OneToOne relationship instead of an Embedded. You also need to remember to use @PrimaryKeyJoinColumn
instead of @JoinColumn
:
@Entity
@Table(name = "bar")
class Bar {
@Id
int fooId;
String y;
String z;
}
...
@Entity
@Table(name = "foo")
class Foo {
@Id
int id;
@OneToOne
@PrimaryKeyJoinColumn
Bar bar;
}
The biggest advantage is that Foo
no longer needs to know about the contents of Bar
. Depending on your DB's naming strategy, you may also need to specify the column name of fooId
in Bar
with something like @Column(name = "foo_id")
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With