H2 - Hibernate 不在 SQL INSERT 上插入默认列值

H2 - Hibernate not inserting Default column values on SQL INSERT

我正在开发一项服务,目前正在处理它的两个实体(SectionGradeLevel) 虽然我还在开发,但我决定使用 H2 并从 Java 代码生成 tables。

Section.java

@Entity
@Setter
@Getter
public class Section{

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

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

    @OneToOne
    private GradeLevel gradeLevel;

    @Column(columnDefinition = "boolean default TRUE")
    private boolean isActive;

    @Column(columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
    private Timestamp dateCreated;

    private Timestamp dateLastUpdated;
}

GradeLevel.java

@Entity
@Getter
@Setter
public class GradeLevel {

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

    @Column(unique = true, nullable = false)
    private String code; //GL-01, GL-02...

    @Column(unique = true)
    private String description; //Kinder 1, Kinder 2, Grade 1....
    private String category; //Elementary School, Junior Highschool, Senior Highschool

    @Column(columnDefinition = "boolean default TRUE")
    private boolean isActive;

    @Column(columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
    private Timestamp dateCreated;

    private Timestamp dateLastUpdated;   
}

SectionRESTController.java

@RestController
@RequestMapping(value = "/api/sections")
public class SectionRESTController {

    @Autowired
    private SectionService sectionService;

    @GetMapping(path = "/{sectionId}")
    public Section getSectionById(@PathVariable("sectionId") Long id) {
        return sectionService.getSectionById(id);
    }

    @PostMapping(consumes = "application/json", produces = "application/json")
    public ResponseEntity<Section> createSection(@Valid @RequestBody SectionCreateDTO sectionCreateDTO) {
        Section createdSection = sectionService.createSection(sectionCreateDTO.toSection());
        if (createdSection == null) {
            return ResponseEntity.notFound().build();
        } else {
            URI uri = ServletUriComponentsBuilder.fromCurrentRequest()
                    .path("/{sectionId}")
                    .buildAndExpand(createdSection.getId())
                    .toUri();
            return ResponseEntity.created(uri)
                    .body(createdSection);
        }
    }
}

SectionCreateDTO.java

@Data
public class SectionCreateDTO {
    @NotEmpty(message = "Section name is required.")
    private String name;

    @NotNull(message = "gradelevel id is required.")
    private Long gradeLevelId;

    public Section toSection() {
        Section section = new Section();
        section.setName(name);

        GradeLevel gradeLevel = new GradeLevel();
        gradeLevel.setId(gradeLevelId);

        section.setGradeLevel(gradeLevel);
        return section;
    }
}

问题: createSection() 控制器方法没有为部分的 IS_ACTIVEDATE_CREATED 列插入 DEFAULT 列值。我已将这两列都设置为 TRUECURRENT_TIMESTAMP default values

Postman 中的示例请求:

POST localhost:8080/api/sections

{
        "name": "MERCURY",
        "gradeLevelId" : 1
}

在 H2 控制台中,Section table 显示这些字段的 NULLFALSE。而不是正确的时间戳和 TRUE 值。

application.properties

#========================================================================
#H2 Properties
#========================================================================
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update

我不知道这个问题是否只针对 H2 或我在这里遗漏了什么。

如有任何意见,我将不胜感激。

====== 编辑。下面是解决方案=======

对我有用的解决方案是:

@Column(columnDefinition = "boolean default true")
private Boolean isActive = true;

@CreationTimestamp
@Column(name = "date_created")
private LocalDateTime dateCreated = LocalDateTime.now();

@UpdateTimestamp
@Column(name = "date_last_updated")
private LocalDateTime dateLastUpdated = LocalDateTime.now();

感谢您的建议和解答。

IS_ACTIVE 列的问题是您使用的是布尔值(默认情况下为 false,但您需要一个空值)而不是布尔值。 对于创建的时间戳,您可以尝试添加 @CreationTimestamp

即使将 boolean 更改为 Boolean,它也不会起作用。

Hibernate 总是发送包括空值在内的所有字段,例如:

INSERT INTO SECTION(..., IS_ACTIVE, ...) VALUES (..., null, ...)

您的数据库会将 NULL 插入 IS_ACTIVE,而不是默认值。

如果要默认为true,请在Java中设置: private Boolean isActive = true;