farahm
farahm

Reputation: 1326

Hibernate mapping user relation to entities

Let's se we have Hibernate entity User with basic fields such as username, password, roles etc..

Now we have an entity such as Car.

User has a OneToOne relationship with Car, cause he can own a car. But he also has besides this a OneToMany relationship to Car, because he also owns the cars of his children. But in the frontend I want to know which cars he owns for himself and which cars he owns for his children. The same applies to the relationship between User and motorbike (his own, his childrens, etc...)

How would the User entity class look like? Is it good to have the relationships mapped in an "Helper" entity such as UserData:

@Entity
@Data
@Table( name = "users",
        uniqueConstraints = {
            @UniqueConstraint(columnNames = "username")
        })
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank
    @Size(max = 150)
    private String username;

    @NotBlank
    @Size(max = 120)
    private String password;

    @OneToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
    @JoinColumn(name = "USER_DATA_ID")
    private UserData userData;

UserData:

@Entity
@Data
@Table( name = "user_data")
public class UserData {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
    @JoinColumn(name = "OWN_CAR_ID")
    private Car ownCar;

    @OneToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
    @JoinColumn(name = "PARTNER_CAR_ID")
    private Car partnerCar;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable( name = "user_children_cars",
            joinColumns = @JoinColumn(name = "user_data_id"),
            inverseJoinColumns = @JoinColumn(name = "car_id"))
    private Set<Car> childrenCars = new HashSet<>();

    public boolean addToChildrenCarSet(Car c) {
        return childrenCars.add(c);
    }

    public UserData() {
    }

}

Upvotes: 0

Views: 160

Answers (1)

Thomas
Thomas

Reputation: 471

As you ask for an opinion, I would say it gets unnecessary complicated if you use the intermediate entity user_data. :-) There is no real drawback to add more fields and keys into the user class - performance is probably also better then using the EAGER fetching. If performance is an issue, better optimize querys later on then splitting the table now.

Also the @ManyToMany I would avoid - better create the intermediate table and relations yourself. You can check out https://bootify.io and create your database schema there. There is no EAGER fetching and also no CascadeType.ALL (both only good ideas in special cases), you would probably add more problems with that then actual helping in any way.

So the addToChildrenCarSet method would end up in a @Service class, in a method with @Transactional, in my proposal.

Upvotes: 1

Related Questions