My data model consists of items with a history. I'll call a point in time an "instant"; all tables therefore have an "instant_id" that specifies how that item was configured at that instant. The "instant_id" is rolled into a composite primary key for all tables. Imagine the following example:
Table Computer
============
PK int instant_id <-- Shared id
PK int computer_id <-- Child id
int computer_type_id <-- Parent id
varchar foo
Table ComputerType
==================
PK int instant_id <-- Shared id
PK int computer_type_id <-- Parent id
varchar bar
There is a foreign key in Computer mapping (instant_id, computer_type_id) to the ComputerType primary key.
We use something like
@Embeddable ComputerId {
@Column(name='instant_id', nullable=false) int instant_id,
@Column(name='computer_id', nullable=false) int computer_id
}
Then:
Computer {
@EmbeddedId ComputerId id;
@MapsId('instant_id')
@ManyToOne
@JoinColumns({
@JoinColumn(name='instant_id',...),
@JoinColumn(name='computer_type_id',...)
})
ComputerType computerType;
}
No matter how I combine MapsId with JoinColumns, I can't seem to get this to work. Any ideas?
I don't see a ManyToOne association. You are not showing us how ComputerType is declared, I am assuming it's an Entity. If that's the case, per table definition you provided, both Computer and ComputerType share a composite primary key: instant_id and computer_type_id .
If that is true and they share the same primary key, you might be better off normalizing those two tables into one table.
I think I understand the issue now. You need to consider the computer_type_id as part of the composite key for Computer table as well. The column computer_type_id by itself is not quite meaningful; in the ComputerType table it is a part of the primary key, the other part being instant_id. So if that's the case, you need to include it as part of the primary key for Computer table as well, because you will never have a case where Computer.instant_id = ComputerType.instant_id AND Computer.computer_type_id <> ComputerType.computer_type_id, for a given related association. (If I understand this case correctly)
If you agree with that, then here is the solution:
@Embeddable
public class ComputerId implements Serializable {
int computer_id;
@ManyToOne
@JoinColumns({@JoinColumn(name = "instant_id", insertable=false, updatable=false),
@JoinColumn(name = "computer_type_id", insertable=false, updatable=false) })
ComputerType computerType;
// getters and setters
}
@Entity
public class Computer {
@EmbeddedId
ComputerId computerId;
// getters and setters
}
public class ComputerTypeId implements Serializable {
@Column(name="instant_id", nullable=false) int instant_id;
@Column(name="computer_type_id", nullable=false) int computer_type_id;
// getters and setters
}
@Entity
public class ComputerType {
@EmbeddedId
ComputerTypeId computerTypeId;
String bar;
// getters and setters
}
Finally, you might want to consider Hibernate Envers for Entity versioning.
Hope this helps.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.