I'm working on a deck building card game using Spring Data and Hibernate. I would like to map the following PostGreSQL tables:
CREATE TABLE Deck(
ID UUID NOT NULL,
name VARCHAR(255) NOT NULL,
PRIMARY KEY(ID)
);
CREATE TABLE DeckEntry(
deckID UUID NOT NULL,
cardID UUID NOT NULL,
cardCount INT NOT NULL,
PRIMARY KEY(deckID, cardID),
CONSTRAINT fk_deckEntry_deck FOREIGN KEY(deckID) REFERENCES Deck(ID) ON DELETE CASCADE
)
The idea here is that:
cardCount
times in a deck.DeckEntry
represents the relationship and contains the count, but has no primary key of its own.Here's what I've got in terms of mappings:
@Entity
public class DeckEntry {
@EmbeddedId
private DeckEntryID id;
@Column
private int cardCount;
// hashCode and equals based on id
}
@Embeddable
public class DeckEntryID {
@Column
private UUID deckID;
@Column
private UUID cardID;
// hashcode & equals based on deckId and cardID
}
@Entity
public class Deck {
@Id
private UUID id;
@Column(name = "name")
private String name;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Set<DeckEntry> entries;
// hashCode and equals based on id
}
My question is: What else do I need in terms of mapping annotations on Deck.entries
to make this work as intended? The main issue here is that the target (DeckEntry
) has a combined primary key, and one of the parts that make up this primary key is the Deck
ID itself. This is crucial information for building the SQL statements, but I don't know how to convey this information to hibernate.
Through some experimentation, I've found the following solution which seems to do exactly what I need:
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "id.deckID")
private Set<DeckEntry> entries;
Note the mappedBy
- I didn't know that it's possible to "step into" an embedded ID by using the dot syntax. I've checked the SQL queries generated by this mapping and they seem to be valid.