Home > Blockchain >  H2 - Hibernate not inserting Default column values on SQL INSERT
H2 - Hibernate not inserting Default column values on SQL INSERT

Time:02-10

I'm developing a service and currently working on 2 of its entities (Section and GradeLevel) While I'm still developing, I decided to use H2 and I generate the tables from Java code.

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

Problem : The createSection() controller method is not inserting the DEFAULT column values for Section's IS_ACTIVE and DATE_CREATED column. I have set both of these 2 columns to have TRUE and CURRENT_TIMESTAMP default values

Sample request in Postman :

POST localhost:8080/api/sections

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

In H2 Console, Section table shows NULL and FALSE for those fields. Instead of the correct timestamp and TRUE value.

H2 Database Section Table Result Set

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

I don't know if this problem is only specific to H2 or maybe I am missing something here.

I'd appreciate any comments.

CodePudding user response:

The issue with IS_ACTIVE column that you are using boolean(it is false by default, but you need a null) instead of Boolean. For created timestamp you can try adding @CreationTimestamp

CodePudding user response:

Even if you change boolean to Boolean, it is not going to work.

Hibernate always sends all fields including nulls, for example:

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

Your DB will insert NULL to IS_ACTIVE, not the default.

If you want the default to be true, set it in Java: private Boolean isActive = true;

  • Related