Search code examples
javaspringjoinunique

How to do joins with unique lookup tables


I have a user table that will have a join column to a lookup table named user_type. The user_type table may only hold four different user types which will be associated with user records. My entity code:

UserEntity.java

package com.entity;

import lombok.*;
import javax.persistence.*;

@Getter
@Setter
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "user")
public class UserEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "user_id")
    @Setter(AccessLevel.NONE)
    private Integer userId;

    @Column(name = "first_name")
    private String firstName;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "user_type_fk")
    private UserTypeEntity userTypeEntity;
}

UserTypeEntity.java

package com.entity;

import lombok.*;
import javax.persistence.*;

@Getter
@Setter
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "user_type")
public class UserTypeEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "user_type_id")
    @Setter(AccessLevel.NONE)
    private Integer userTypeId;

    @Column(name = "user_type")
    private String userType;

    @OneToMany(mappedBy = "userTypeEntity")
    private Set<UserEntity> userEntities;
}

When I save a new UserEntity, a new UserTypeEntity is also saved. I would like it to behave differently. I would like it to only save a new UserEntity if the user_entity column of the user_entity table does not hold the incoming value. Is this something that is best handled in the service layer? Or is there some way to signify to hibernate that this should be done?

Everything below here is a verbose elaboration of the question stated above.

Let's say I have, in my user_type table this row:

user_type_id = 3, user_type = "admin"

And I have a user table with this row:

user_id = 9, first_name = "Adam", user_type_fk = 3

I want to add this new user:

user_id = 10, first_name = "Joe", user_type = "admin"

Using the entity code above, if I saved Joe using userDao.save(joeUser), the user table would add joe, but so would the user_type table, which would result in this user_type table:

user_type_id = 3, user_type = "admin"
user_type_id = 4, user_type = "admin"

And this user table:

user_id = 9, first_name = "Adam", user_type_fk = 3
user_id = 10, first_name = "Joe", user_type_fk = 4

This is something I don't want. I want the user_type column to be unique. If a new user is an admin, I don't want a new admin record added to the user_type table. I want the existing one assigned to the new user instead. I want the result of the userType table to be this:

user_type_id = 3, user_type = "admin"

And the user table to be this:

user_id = 9, first_name = "Adam", user_type_fk = 3
user_id = 10, first_name = "Joe", user_type_fk = 3

Is this best done in the service layer by finding an existing user_type record, then creating one if it doesn't exist? Or is there a way for Hibernate to handle this with some annotation?


Solution

  • Hibernate requires the ID (PK) of the record you want to link to, else it assumes you want to create a new record. You'll need to do a lookup to get the relevant user type record, and then assign that object to the field on your UserEntity object and you'll get what you want. This you should do in your service layer.