英文:
The increment size of the sequence is set to [50] in the entity mapping while the associated database sequence increment size is [1]
问题
以下是翻译好的部分:
我正在跟随在Udemy上的“Learn Spring 5”课程,我现在正在测试我们的应用程序的部分。一切都很顺利,直到现在,我能够连接到PostgreSQL数据库,但是现在我已经困在这个测试失败的地方已经有2天了。
我不明白是什么原因导致测试失败。应用程序运行正常,但测试没有通过。以下是测试类的代码:
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());
}
}
这是堆栈跟踪信息:
Employee类(不用关心注释,它们可能是无用的):
package com.ghevi.pma.entities;
import javax.persistence.*;
import java.util.List;
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "employee_seq")
private long employeeId;
private String firstName;
private String lastName;
private String email;
@ManyToMany(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.PERSIST},
fetch = FetchType.LAZY)
@JoinTable(name = "project_employee",
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;
}
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;
}
}
这是schema.sql
文件,其中我引用了这些序列。由于这个文件是由测试运行的,我刚刚注意到IntelliJ在这个文件中标记了一些错误。例如,它在某些空格和TABLE的T字母上标记了红色,并显示:
CREATE SEQUENCE IF NOT EXISTS employee_seq;
CREATE TABLE IF NOT EXISTS employee (
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 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 (
project_id BIGINT REFERENCES project,
employee_id BIGINT REFERENCES employee
);
英文:
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
);
答案1
得分: 62
Sure, here is the translated code:
你从不告诉它关于序列的事情,只告诉它生成器的名称
尝试一下
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "employee_generator")
@SequenceGenerator(name = "employee_generator", sequenceName = "employee_seq", allocationSize = 1)
英文:
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)
答案2
得分: 9
我遇到了同样的问题。添加以下注释后问题得以解决。 @SequenceGenerator(name = "employee_seq", allocationSize = 1)
英文:
I had the same issue. Adding the below annotation resolved it. @SequenceGenerator(name = "employee_seq", allocationSize = 1)
答案3
得分: 2
默认情况下,SequenceGenerator
中的 allocationSize
参数设置为 50。当您的序列增量不匹配时,就会出现此问题。您可以更改序列增量值,或根据您的需求分配 allocationSize
大小。
英文:
By default allocationSize
parameter in SequenceGenerator is set to be 50. This problem arises when your sequence increment mismatches. You can either change the sequence increment value or assign allocationSize size as per your requirement.
答案4
得分: 1
或许,在雇员实体中生成器的定义存在问题。
“生成器”必须是SequenceGenerator的“名称”,而不是诸如序列之类的其他名称。也许是因为您给了序列的名称,但没有具有该名称的生成器,它使用了默认的预分配,即50。
另外,策略应为SEQUENCE,但如果您定义了生成器,则不需要,它只在您没有定义生成器时才相关。
英文:
Perhaps, there is something wrong with the generator definition in the employee entity.
The "generator" must be the "name" of the SequenceGenerator, not the name of other things such as the sequence. Maybe Because you gave the name of the sequence, and did not have a generator with that name it used the default preallocation which is 50.
Also, the strategy should be SEQUENCE, but isn't required if you define the generator, it is only relevant when you don't define the generator.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论