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

Posted

技术标签:

【中文标题】序列的增量大小在实体映射中设置为 [50],而关联的数据库序列增量大小为 [1]【英文标题】:The increment size of the sequence is set to [50] in the entity mapping while the associated database sequence increment size is [1] 【发布时间】:2021-08-12 15:21:18 【问题描述】:

我正在关注 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());
    


这是堆栈跟踪:

https://pastebin.com/WcjNU76p

员工类(不要介意cmets,他们可能是垃圾):

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

);

【问题讨论】:

将堆栈跟踪添加为文本而不是链接 读取错误信息: *实体映射中[employee_seq]序列的增量大小设置为[50],而关联的数据库序列增量大小为[1]。 我无法添加堆栈跟踪,因为它有太多字符:/ 而且教程中的那个人在启动测试时也有这个警告,但它没有通过他的测试。 @Ghevi 请附上Employee类 另外,将堆栈末尾的错误消息的标题更改为:“[employee_seq] 序列的增量大小在实体映射中设置为 [50] 而关联的数据库序列增量大小为 [1]。” 【参考方案1】:

也许,员工实体中的生成器定义有问题。 “生成器”必须是序列生成器的“名称”,而不是序列等其他事物的名称。也许是因为您给出了序列的名称,并且没有具有该名称的生成器,所以它使用了默认的预分配,即 50。

此外,策略应该是 SEQUENCE,但如果您定义了生成器,则不需要它,它仅在您未定义生成器时才相关。

【讨论】:

我附加了 Employee 类,其中策略确实是 SEQUENCE。我现在有点迷茫,你在哪里定义 SequenceGenerator?我记得曾给某个人命名了employee_seq 和project_seq,就像在这两个实体中一样/跨度> 【参考方案2】:

你从不告诉它序列,只告诉它生成器的名称

试试

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "employee_generator")
@SequenceGenerator(name = "employee_generator", sequenceName = "employee_seq", allocationSize = 1)

【讨论】:

这解决了错误,但现在我有另一个错误:GenerationTarget 遇到异常接受命令:执行 DDL 时出错“创建表项目(project_id bigint 不为空,描述 varchar(255),名称 varchar(255), stage varchar(255), primary key (project_id))" via JDBC Statement @Ghevi 我需要查看项目类【参考方案3】:

我有同样的问题。添加以下注释解决了它。 @SequenceGenerator(name = "employee_seq", allocationSize = 1)

【讨论】:

以上是关于序列的增量大小在实体映射中设置为 [50],而关联的数据库序列增量大小为 [1]的主要内容,如果未能解决你的问题,请参考以下文章

Propper实体关联与一个实体映射为连接表(Doctrine 2)

abp 修改abp.zero的实体映射类,使生成的表和字段为大写状态

与连接表的一个实体的适当实体关联映射(学说 2)

如何使用查询而不是带有 JPA 的 @JoinColumn 映射实体关联?

hibernate学习---关联关系映射

WCF+Nhibernate循环引用导致序列化的问题