H2 - Hibernate 不在 SQL INSERT 上插入默认列值
H2 - Hibernate not inserting Default column values on SQL INSERT
我正在开发一项服务,目前正在处理它的两个实体(Section
和 GradeLevel
)
虽然我还在开发,但我决定使用 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_ACTIVE
和 DATE_CREATED
列插入 DEFAULT
列值。我已将这两列都设置为 TRUE
和 CURRENT_TIMESTAMP
default values
Postman 中的示例请求:
POST localhost:8080/api/sections
{
"name": "MERCURY",
"gradeLevelId" : 1
}
在 H2 控制台中,Section
table 显示这些字段的 NULL
和 FALSE
。而不是正确的时间戳和 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;
我正在开发一项服务,目前正在处理它的两个实体(Section
和 GradeLevel
)
虽然我还在开发,但我决定使用 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_ACTIVE
和 DATE_CREATED
列插入 DEFAULT
列值。我已将这两列都设置为 TRUE
和 CURRENT_TIMESTAMP
default values
Postman 中的示例请求:
POST localhost:8080/api/sections
{
"name": "MERCURY",
"gradeLevelId" : 1
}
在 H2 控制台中,Section
table 显示这些字段的 NULL
和 FALSE
。而不是正确的时间戳和 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;