I have four Entities , an Gorilla, a Health Check, Transmitter and a Microchip - I have a question about wiring these entities together.
Gorillas have Health Checks 3-4 times a year so they are OneToMany. Each Gorilla normally has 1 microchip during the course of there life. Microchips are inserted during health checks, but usually only one unless one has fallen out (rare). So I make this OneToMany also on Gorilla to Microchip. Each Gorilla has one Transmitter at a time, but they are replaced every year. So also OneToMany.
I have setup my entities like this:
GORILLA
@Data
public class Gorilla {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
@Column(unique = true)
@NotEmpty(message = "Name must not be null or empty")
private String name;
@JsonIgnore
@OneToMany (cascade = { CascadeType.DETACH, CascadeType.MERGE, CascadeType.MERGE, CascadeType.REFRESH}, orphanRemoval = true, mappedBy = "gorilla")
private List<Microschip> listMicroschip = new ArrayList<>();
@JsonIgnore
@OneToMany (cascade = { CascadeType.DETACH, CascadeType.MERGE, CascadeType.MERGE, CascadeType.REFRESH}, orphanRemoval = true, mappedBy = "gorilla")
private List<Transmitter> listTransmitter = new ArrayList<>();
@JsonIgnore
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "gorilla")
private List<HealthCheck> listHealthCheck = new ArrayList<>();
MICROCHIP
@Data
public class Microchip {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
@Column(unique = true)
@NotEmpty(message = "Name must not be null or empty")
private String code;
private LocalDate dateInserted;
@ManyToOne(fetch = FetchType.LAZY, optional = true)
private Gorilla gorilla;
HEALTHCHECK
@Data
public class HealthCheck {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private Gorilla gorilla;
// other stuff
When viewing the gorilla entity as a list or a single i normally get the Gorilla with Name, current transmitter, current microchip and sometimes a list of summary fields for the health check.
When viewing a HealthCheck want to retrieve it with Gorilla details, any microchips or transmitters that were attached during that HealthCheck.
The problem with the current design with the Microchips and Transmitters having a relationship with the Gorilla is it makes it easy to get a Gorilla with its current (most recent) transmitter and (most recent) microchip.
This design however makes it hard to get a healthcheck and see which microchip or transmitter was attached on that healthcheck (if any were).
My code for getting the newest microchip for example is:
default void helperMapping(Gorilla source, GorillaDTO target) {
if (!source.getListTransmitter().isEmpty()) {
Transmitter trans = (source.getListTransmitter()
.stream()
.max(Comparator.comparing(Transmitter::getDateAttached)).get());
target.setChannel(trans.getChannel());
target.setChannelOffset(trans.getChannelOffset());
}
How can I setup the ORM so that:
- I don't have to stream over the list of Gorilla's transmitters/microchips each time I want the current one - seems very in-efficent.
- I can retrieve a list of healthchecks with any microchips or transmitters relevant to that healthcheck
- Less common get a list of all transmitters/microchips for a given Gorilla
(PS: I also tried microchip/transmitter sitting under HealthCheck but they made it even hard to get current microchip/transmitter)
UPDATE
I am considering having a two relationships: Gorilla (One) to Transmitter (Many) HealthCheck (One) to Transmitter (One and Optional)
This way I could easily find the newest Transmitter for any Gorilla (newest in list) and I can see which health check a transmitter was created in.
Thoughts?