Home > Enterprise >  Why Hibernate adds new role instead of adding role id in foreign key column?
Why Hibernate adds new role instead of adding role id in foreign key column?

Time:11-11

In my spring boot project I use PostgreSQL and Hibernate. I created 2 tables for user and separate table for role, create entities:

@Entity
@Table(name = "user_account")
public class UserAccount {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @NotNull
    @Column(name = "username")
    private String userName;

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

    @NotNull
    @Column(name = "last_name")
    private String lastName;

    @NotNull
    @Column(name = "password")
    private String password;

    @CreationTimestamp
    @Column(name = "birthday")
    private LocalDateTime birthday;

    @NotNull
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "role", referencedColumnName = "id")
    private UserRole role;
}

and for role:

@Entity
@Table(name = "role")
public class UserRole {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @Enumerated(value = EnumType.STRING)
    @Column(name = "name")
    private RoleName name;
}

Code of controller:

@PostMapping(value = "")
UserAccountDTO create(@RequestBody UserAccount user) {
    return userService.create(user);
}

UserService method create():

    @Override
    public UserAccountDTO create(UserAccount user) {
        UserAccount recordedUser = userRepository.save(user);
    
        return modelMapper.map(recordedUser, UserAccountDTO.class);
    }

UserRepository(based on Spring-Data JPA):

    @Repository
    public interface UserRepository extends JpaRepository<UserAccount, Integer> {
    }

dto:

public class UserAccountDTO {
    private Integer id;
    private String username;
    private String firstName;
    private String lastName;
    private LocalDateTime birthday;
    private UserRole role;
}

In table role I already created 2 roles - ADMIN, CLIENT(default values). So I want to implement functionality when you can add user and simply write role_id in column which refers to role table as one-to-one. So during insert it shoild add record with new user with role id key which refers to necessary role-record I have to send post requests I have to send such JSON:

{
    "firstName": "test1",
    "lastName": "user",
    "password": "test",
    "username": "[email protected]",
    "role": {
        "id": 2,
        "name": "CLIENT"
    }
}

Hibernate creates user recored, but also it adds new role record with name CLIENT and this is wrong. Why and what I'm doing wrong?

CodePudding user response:

The issue seems to be that you are indeed including a role with an ID in your request. The problem is that this role is just a regular object and not an entity that Hibernate knows or that is related in any way with data already in the database.

Having written this, you will need to get the corresponding role from the database and set it in UserAccount you want to create. This means that you need to update your UserService.create() method accordingly:

@Override
public UserAccountDTO create(UserAccount user) {
    UserRole userRole = userRoleRepository.findByName(user.getNam()); // I would suggest getting it by name instead of by ID
    user.setRole(userRole);
    UserAccount recordedUser = userRepository.save(user);

    return modelMapper.map(recordedUser, UserAccountDTO.class);
}

As a side note, just like you have a DTO for the response, you should also have a DTO for the request. Using Entities as response or request in your Controller is a bad practice and should be avoided. I would suggest you create the following DTO for the request:

public class UserAccountCreationRequestDto {
    private String userName;
    private String firstName;
    private String lastName;
    private String password;
    private LocalDateTime birthday;
    private RoleName roleName;
}
  • Related