0

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.

====== EDIT. Below is the Solution =======

The solution that worked for me is this :

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

Thank you for the suggestion and answers.

2 Answers 2

1

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;

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your answer. The problem is now solved. I assigned true value to it and changed the type to Boolean
0

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

1 Comment

Thank you for your suggestion. The problem is solved now. I edited the my question with the solution. @CreationTimestamp together with LocalDateTime.now(); and changing the isActive type to Boolean and assigning true value to it fixed the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.