实体映射中序列的增量大小设置为[50],而关联的数据库序列增量大小为[1]。

26

我是您的助手,以下是您需要翻译的内容:

我正在跟随Udemy上的Learn Spring 5等课程,现在到了测试应用程序的部分。到目前为止一切都正常,我能够连接到PostgreSQL数据库,但是现在我被卡在这个测试失败的地方已经两天了。

我不明白是什么原因导致测试失败。应用程序可以运行,但测试不行。以下是测试类:

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());
    }

}

以下是堆栈跟踪:

https://pastebin.com/WcjNU76p

员工类(请忽略注释,它们可能是垃圾):

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;
    }
}

此外,这是我引用那些序列的schema.sql文件,因为该文件由测试运行,我刚刚注意到IntelliJ在该文件中标记了一些错误。例如,它将某些空格和TABLE中的T标记为红色。
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

);

将堆栈跟踪作为文本添加,而不是作为链接。 - Jens
阅读错误信息: *员工序列[employee_seq]的增量大小在实体映射中设置为[50],而关联的数据库序列增量大小为[1]。 - Jens
我无法添加堆栈跟踪,因为它有太多字符 :/ 教程中的那个人在启动测试时也有这个警告,但它不会导致测试失败。 - ScottexBoy
@Ghevi 请附上Employee类。 - user3359139
此外,将堆栈底部的错误消息标题更改为:“实体映射中 [employee_seq] 序列的增量大小设置为 [50],而关联的数据库序列的增量大小为 [1]。” - user3359139
我做了一些编辑,希望现在更清晰了。我的大脑正在崩溃,唉。 - ScottexBoy
4个回答

70
你永远不会告诉它序列的情况,只需告诉它生成器的名称。
尝试
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "employee_generator")
@SequenceGenerator(name = "employee_generator", sequenceName = "employee_seq", allocationSize = 1)

这解决了错误,但现在我又遇到了另一个错误:GenerationTarget 遇到异常接受命令:通过 JDBC Statement 执行 DDL "create table project (project_id bigint not null, description varchar(255), name varchar(255), stage varchar(255), primary key (project_id))" 时出错。 - ScottexBoy
@Ghevi 我需要看一下项目类。 - 123

10

我曾经遇到过相同的问题。添加以下注释即可解决:

@SequenceGenerator(name = "employee_seq", allocationSize = 1)

2

默认情况下,SequenceGenerator中的allocationSize参数设置为50。当您的序列增量不匹配时,会出现此问题。您可以更改序列增量值或根据需要指定分配大小。


1
也许,在员工实体中生成器定义存在问题。 "generator" 必须是 SequenceGenerator 的 "name",而不是其他事物(如序列)的名称。也许因为您提供了序列的名称,但没有使用该名称的生成器,所以它使用了默认的预分配,即 50。
另外,策略应该是 SEQUENCE,但如果您定义了生成器,则不需要该策略,只有在您没有定义生成器时才相关。

我附加了Employee类,其中策略确实是SEQUENCE。现在我有点迷失了,在哪里定义SequenceGenerator?我记得有人把employee_seq和project_seq命名为某些东西,就像这两个实体中的一样。编辑:是的,我记得我在schema.sql中将它们命名为:employee_id BIGINT NOT NULL DEFAULT nextval('employee_seq')PRIMARY KEY - ScottexBoy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接