0



I am working on project using Spring Boot (version 3.0.5). I am trying to test UserRepository if my Client and Hairdresser(which are the children of the User class) are saved fine in the repo. However, I get an error whilst trying to save the Client, Hairdresser works fine.


UserRepositoryTest.java:

package com.edoyou.k2sbeauty.repositories;

import com.edoyou.k2sbeauty.entities.model.Client;
import com.edoyou.k2sbeauty.entities.model.Hairdresser;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;

import java.time.LocalDateTime;

import static org.assertj.core.api.Assertions.assertThat;

@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestPropertySource(locations = "classpath:application-test.properties")
public class UserRepositoryTest {
    @Autowired
    private UserRepository userRepository;
    private Client client;
    private Hairdresser hairdresser;

    @BeforeEach
    void setUp() {
        client = new Client();
        client.setFirstName("Barbara");
        client.setLastName("O'Conner");
        client.setEmail("myemail@gmail.com");
        client.setPassword("password");
        client.setPhone("36707733373");
        client.setCreatedAt(LocalDateTime.now());
        client.setUpdatedAt(LocalDateTime.now());

        hairdresser = new Hairdresser();
        hairdresser.setFirstName("Jane");
        hairdresser.setLastName("Doe");
        hairdresser.setEmail("jane.doe@gmail.com");
        hairdresser.setPassword("password");
        hairdresser.setPhone("36707733444");
        hairdresser.setCreatedAt(LocalDateTime.now());
        hairdresser.setUpdatedAt(LocalDateTime.now());
        hairdresser.setSpecialization("Hairstyling");
    }

    @Test
    public void shouldSaveClient() {
        Client savedClient = userRepository.save(client);
        assertThat(savedClient).isNotNull();
        assertThat(savedClient.getId()).isNotNull();
    }

    @Test
    public void shouldSaveHairdresser() {
        Hairdresser savedHairdresser = userRepository.save(hairdresser);
        assertThat(savedHairdresser).isNotNull();
        assertThat(savedHairdresser.getId()).isNotNull();
    }
}

shouldSaveHairdresser() test is fine, shouldSaveClient() test method fails.

User.java:

package com.edoyou.k2sbeauty.entities.model;

import jakarta.persistence.*;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "users")
public class User {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @Column(nullable = false)
  private String firstName;

  @Column(nullable = false)
  private String lastName;

  @Column(nullable = false, unique = true)
  private String email;

  @Column(nullable = false)
  private String password;

  @Column(nullable = false)
  private String phone;

  @Column(nullable = false)
  private LocalDateTime createdAt;

  @Column(nullable = false)
  private LocalDateTime updatedAt;

  @ManyToMany(fetch = FetchType.LAZY)
  @JoinTable(name = "user_roles",
      joinColumns = @JoinColumn(name = "user_id"),
      inverseJoinColumns = @JoinColumn(name = "role_id"))
  private Set<Role> roles = new HashSet<>();

  public void setId(Long id) {
    this.id = id;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  public void setEmail(String email) {
    this.email = email;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public void setPhone(String phone) {
    this.phone = phone;
  }

  public void setCreatedAt(LocalDateTime createdAt) {
    this.createdAt = createdAt;
  }

  public void setUpdatedAt(LocalDateTime updatedAt) {
    this.updatedAt = updatedAt;
  }

  public void setRoles(Set<Role> roles) {
    this.roles = roles;
  }

  public Long getId() {
    return id;
  }

  public String getFirstName() {
    return firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public String getEmail() {
    return email;
  }

  public String getPassword() {
    return password;
  }

  public String getPhone() {
    return phone;
  }

  public LocalDateTime getCreatedAt() {
    return createdAt;
  }

  public LocalDateTime getUpdatedAt() {
    return updatedAt;
  }

  public Set<Role> getRoles() {
    return roles;
  }
}

Hairdresser.java:

package com.edoyou.k2sbeauty.entities.model;

import jakarta.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "hairdressers")
public class Hairdresser extends User {
  @Column(nullable = false)
  private String specialization;

  @OneToMany(mappedBy = "hairdresser")
  private Set<Appointment> appointments = new HashSet<>();

  public void setSpecialization(String specialization) {
    this.specialization = specialization;
  }

  public void setAppointments(Set<Appointment> appointments) {
    this.appointments = appointments;
  }

  public String getSpecialization() {
    return specialization;
  }

  public Set<Appointment> getAppointments() {
    return appointments;
  }
}

Client.java:

package com.edoyou.k2sbeauty.entities.model;

import jakarta.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "clients")
public class Client extends User {
  @OneToMany(mappedBy = "client")
  private Set<Appointment> appointments = new HashSet<>();

  public void setAppointments(Set<Appointment> appointments) {
    this.appointments = appointments;
  }

  public Set<Appointment> getAppointments() {
    return appointments;
  }
}

ERROR:

2023-04-27 10:20:42.145 ERROR 43965 --- [main] o.h.e.j.s.SqlExceptionHelper             : Field 'specialization' doesn't have a default value


Here is the full view of the database tables:

---

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
EDOYou
  • 25
  • 4
  • That's because you have specified `@Column(nullable = false)` and the value when inserting is null, therefore, it will raise an exception. You can set a default value in the database engine or in the code – Leonardo Emmanuel de Azevedo Apr 27 '23 at 08:58
  • I actually tried to set it to **true** as well, I get exactly the same error message. I don't understand the connection between `Client` and `Hairdresser` actually. If my hairdresser-related method failed, I would understand somehow. I get an error whilst running **shouldSaveClient()** – EDOYou Apr 27 '23 at 10:00
  • How does the table look like? Can you print the SQL to see what's happening? – Leonardo Emmanuel de Azevedo Apr 27 '23 at 12:37
  • Sorry for the late response, I edited my question above, view of the database added. – EDOYou Apr 28 '23 at 06:34
  • Please do not edit solution announcements into the question. Accept (i.e. click the "tick" next to it) one of the existing answer, if there are any. You can also create your own answer, and even accept it, if your solution is not yet covered by an existing answer. Compare https://stackoverflow.com/help/self-answer – Yunnosch Apr 28 '23 at 19:50

1 Answers1

0

There were reasons that UserRepositoryTest was failing.

  • First, @Inheritance(strategy = InheritanceType.JOINED) annotation should have added right above the User class as it is the base class for Client and Hairdresser. Here is the modified form of the User class:
@Entity
@Table(name = "users")
@Inheritance(strategy = InheritanceType.JOINED)
public class User { ... }
  • Second, there was a problem with my database as it was changed during the development and not updated. So, the solution was dropping the table, and it's done by adding create-drop to the configuration file, in my case it's application.properties:
spring.jpa.hibernate.ddl-auto=create-drop
EDOYou
  • 25
  • 4
  • 1
    Be aware that `create-drop` will drop the database once the application is stopped. Follow [this](https://stackoverflow.com/questions/42135114/how-does-spring-jpa-hibernate-ddl-auto-property-exactly-work-in-spring) – Leonardo Emmanuel de Azevedo Apr 29 '23 at 11:00