user345 user345 - 3 months ago 15
Java Question

JPA Hibernate :: Inheritance of an entity, with additional OneToMany Lists

I'm using JPA Hibernate/Spring boot to build a web server with MySQL database, and I'm trying to extend a POJO Entity that looks like this, with additional OneToMany Lists.

@Entity
@Table(name="user")
public class User {
@Id
@GeneratedValue
private Integer id;

@Column(nullable=false)
private String name;

....Constructors, getters and setters....
}


with this basic user entity, I just wanna make a UserInfo entity with additional information about the user's careers.

@Entity
public class UserInfo extends User {

@OneToMany(cascade= CascadeType.ALL, fetch= FetchType.EAGER)
@JoinColumn(name="user_id", referencedColumnName = "id")
private List<Career> careers;

....Constructors, getters, setters......
}


And I'm quite confused which inheritance strategy I should choose. I don't think its necessary to make another column or table for this.
Or should I just query twice..?

I'm kinda new to JPA so not sure which is considered as the best practice or design..

Edit:

This is how Career entity looks like. Just in case..

@Entity
@Table(name="career")
public class Career {
@Id
@GeneratedValue
private Integer id;

@Column(nullable=false)
private Integer user_id;

@Column(nullable=false)
private String name;

@Column(nullable=false)
private String description;

....Constructors, getters and setters....
}


Since extending User table was meaningless(just in my case), I changed the
User
class like this.

@Table(name="user")
public class User {
@Id
@GeneratedValue
private Integer id;

@Column(nullable=false)
private String name;

@OneToMany(fetch= FetchType.LAZY)
@JoinColumn(name="user_id", referencedColumnName = "id")
private List<Career> careers;

....Constructors, getters, setters......

}


Now I'm trying this with Spring Data JPA, and when I try to show the list of Users with their Careers, it is now querying more than 40 times taking about a minute to show the result.

Is this the N+1 problem..? how can I solve this?

Answer

In my opinion the error lies within the model itself. Why should UserInfo extend User? I cannot imagine which attributes or methods the UserInfo should inherit from a User. Typical inheritances would be "Developer" or "Administrator".

Why don't you add UserInfo as a 1:1 relation in your User entity? Another option is to omit UserInfo and put the Careers as a 1:n relation right into your User.

To prevent possible n+1 issues on a growing number of Careers you might want to change the fetch mode. See below

@OneToMany(fetch=FetchType.LAZY,mappedBy="user")
@Fetch(FetchMode.SUBSELECT)
private Set<Career> careers = new HashSet<>();