'Java ORM vs multiple entities

I have a class Health Check - as part of the class I record how many parasites are seen (enum NONE, SOME, MANY) and also the location of the parasites (enum HEAD, FEET, BODY).

Two ways this could be done:

METHOD 1

Health Check

@Entity
public class HealthCheck {
    @Id
    @GeneratedValue(strategy = AUTO)
    private Long id;
    private Parasite parasite;

Parasite

public class Parasite {
    private BodyLocation bodyLocation;
    private Coverage coverage;
}

Or I could have:

METHOD 2

@Entity
public class HealthCheck {
    @Id
    @GeneratedValue(strategy = AUTO)
    private Long id;
    private ParasiteNumber parasiteNumber;
    private ParasiteLocation parasiteLocation;

Would method 1 require @Entity on parasite class and a entry in the table for each Health Check and a @OneToOne annotation?

Note Parasite class is not used anywhere else. Its only a part of a Health Check.

Which way is correct?



Solution 1:[1]

Generally speaking, yes. In ORM (aka JPA or Hibernate), you are building a graph of objects that represent things in your database. Anything that one @Entity touches is also an @Entity because it's a graph.

Whether it's a @OneToOne or a @ManyToOne, etc, depends on the nature of your data model. But, keep in mind, those connections can also be @Lazy, so they are not loaded until they are needed.

Because of @Lazy, method 2 might be preferred, idk. I assume ParasiteLocation and ParasiteNumber is some sort of join-table. If that's the case, you could load a HealthCheck with its PL and PN, but those objects could be Lazy to Parasite.

I don't think there is a one-size-fits-all answer to your question. It very much depends. But good news, ORM is flexible to cover any/all scenario you might have.

Solution 2:[2]

If Parasite is only used in HealthCheck class,which can be seen as an association. Association means that the existence of child class is dependent on the existence of the parent so it has no independent lifecycle ,thus you can either declare the attributes directly in HealthCheck as you did in your second example ,or you can declare them in Parasite class and then make it Embeddable inside the HealthCheck class,e.g:

/*To embed a class inside in Entity you must declare it Embeddable via the JPA 
annotation @Embeddable */
@Embeddable
public class Parasite {
@Column(name="body_location")
private BodyLocation bodyLocation;
@Column(name="coverage")
private Coverage coverage;

}

@Entity
public class HealthCheck {
@Id
@GeneratedValue(strategy = AUTO)
private Long id;

@Embedded
private Parasite parasite;
}

Here your HealthCheck db table will have the attributes specified in the Parasite class,and note that Parasite table won't be created since it is Embedded and not an Entity (@Entity).

Hope this helps!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jeff Bennett
Solution 2 karim farhouti