I’m following the Learn Spring 5 etc on udemy and I’m at the part where we test our application. Everything worked fine till now, i was able to connect to the postgreSQL database and all but now I’m stuck at this test failing since 2 days.
I don’t understand what is causing the Test to fail. The application run but the test doesn’t. Here it is the test class:
package com.ghevi.dao; import com.ghevi.pma.ProjectManagementApplication; import com.ghevi.pma.dao.ProjectRepository; import com.ghevi.pma.entities.Project; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlGroup; import org.springframework.test.context.junit4.SpringRunner; import static org.junit.Assert.assertEquals; @ContextConfiguration(classes= ProjectManagementApplication.class) @RunWith(SpringRunner.class) @DataJpaTest // for temporary databases like h2 @SqlGroup({ @Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = {"classpath:schema.sql", "classpath:data.sql"}), @Sql(executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, scripts = "classpath:drop.sql") }) public class ProjectRepositoryIntegrationTest { @Autowired ProjectRepository proRepo; @Test public void ifNewProjectSaved_thenSuccess(){ Project newProject = new Project("New Test Project", "COMPLETE", "Test description"); proRepo.save(newProject); assertEquals(5, proRepo.findAll().size()); } }
And this is the stack trace:
Employee class (don’t mind the comments, they are probably garbage):
package com.ghevi.pma.entities; import javax.persistence.*; import java.util.List; @Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "employee_seq") // AUTO for data insertion in the class projmanagapplication (the commented out part), IDENTITY let hibernate use the database id counter. private long employeeId; // The downside of IDENTITY is that if we batch a lot of employees or projects it will be much slower to update them, we use SEQUENCE now that we have schema.sql (spring does batch update) private String firstName; private String lastName; private String email; // @ManyToOne many employees can be assigned to one project // Cascade, the query done on projects it's also done on children entities @ManyToMany(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.PERSIST}, // Standard in the industry, dont use the REMOVE (if delete project delete also children) or ALL (because include REMOVE) fetch = FetchType.LAZY) // LAZY is industry standard it loads project into memory, EAGER load also associated entities so it slows the app, so we use LAZY and call child entities later //@JoinColumn(name="project_id") // Foreign key, creates a new table on Employee database @JoinTable(name = "project_employee", // Merge the two table using two foreign keys joinColumns = @JoinColumn(name="employee_id"), inverseJoinColumns = @JoinColumn(name="project_id")) private List<Project> projects; public Employee(){ } public Employee(String firstName, String lastName, String email) { this.firstName = firstName; this.lastName = lastName; this.email = email; } public List<Project> getProjects() { return projects; } public void setProjects(List<Project> projects) { this.projects = projects; } /* Replaced with List<Project> public Project getProject() { return project; } public void setProject(Project project) { this.project = project; } */ public long getEmployeeId() { return employeeId; } public void setEmployeeId(long employeeId) { this.employeeId = employeeId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
Also this is the schema.sql
where i reference those sequences, since this file is run by the test, i have just noticed that IntelliJ mark some errors in this file. For example it mark red some spaces and the T of TABLE saying:
expected one of the following: EDITIONING FORCE FUNCTION NO OR PACKAGE PROCEDURE SEQUENCE TRIGGER TYPE VIEW identifier
CREATE SEQUENCE IF NOT EXISTS employee_seq; CREATE TABLE IF NOT EXISTS employee ( <-- here there is an error " expected: " employee_id BIGINT NOT NULL DEFAULT nextval('employee_seq') PRIMARY KEY, email VARCHAR(100) NOT NULL, first_name VARCHAR(100) NOT NULL, last_name VARCHAR(100) NOT NULL ); CREATE SEQUENCE IF NOT EXISTS project_seq; CREATE (the error i described is here -->) TABLE IF NOT EXISTS project ( project_id BIGINT NOT NULL DEFAULT nextval('project_seq') PRIMARY KEY, name VARCHAR(100) NOT NULL, stage VARCHAR(100) NOT NULL, description VARCHAR(500) NOT NULL ); CREATE TABLE IF NOT EXISTS project_employee ( <--Here again an error "expected:" project_id BIGINT REFERENCES project, employee_id BIGINT REFERENCES employee );
Advertisement
Answer
You never tell it to about the sequence, just what the generator is called
Try
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "employee_generator") @SequenceGenerator(name = "employee_generator", sequenceName = "employee_seq", allocationSize = 1)