I am encountering an issue with Hibernate when trying to insert a record into my database. Here are the details of the problem:
Problem Description: I’m using Hibernate with Spring Boot to persist data to an H2 database. When attempting to save a new record into the ‘device’ table, Hibernate throws an error stating “NULL not allowed for column ‘ID'”. I have defined the ‘ID’ column as a primary key with auto-increment in the database schema.
Database Schema:
<changeSet id="0003-1" author="mwietecki">
<createTable tableName="device">
<column name="id" type="BIGINT">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="manufacturer" type="VARCHAR(255)"/>
<column name="model" type="VARCHAR(255)"/>
<column name="ram" type="INT"/>
<column name="rom" type="INT"/>
<column name="color" type="VARCHAR(50)"/>
<column name="spec" type="VARCHAR(255)"/>
<column name="quantity" type="INT"/>
</createTable>
</changeSet>
Entity class:
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "device")
public class Device {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String manufacturer;
private String model;
private int ram;
private int rom;
private String color;
@Enumerated(EnumType.STRING)
@Column(columnDefinition = "VARCHAR(255)")
private Spec spec;
private int quantity;
}
Dto class:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DeviceDto {
private Long id;
private String manufacturer;
private String model;
private int ram;
private int rom;
private String color;
private String spec;
private int quantity;
}
DeviceMapper:
@Mapper
public interface DeviceMapper {
DeviceMapper INSTANCE = Mappers.getMapper(DeviceMapper.class);
@Mapping(target = "spec", source = "spec", qualifiedByName = "specToString")
DeviceDto deviceToDeviceDto(Device device);
@Mapping(target = "spec", source = "spec", qualifiedByName = "stringToSpec")
@Mapping(target = "id", ignore = true)
Device deviceDtoToDevice(DeviceDto deviceDto);
@Named("specToString")
default String mapSpecToString(Spec spec) {
return spec != null ? spec.name() : null;
}
@Named("stringToSpec")
default Spec mapStringToSpec(String spec) {
return spec != null ? Spec.valueOf(spec) : null;
}
}
Method addDevice in Service and Controller class:
public DeviceDto addDevice(DeviceDto deviceDto) {
Device device = DeviceMapper.INSTANCE.deviceDtoToDevice(deviceDto);
Device savedDevice = deviceRepository.save(device);
return DeviceMapper.INSTANCE.deviceToDeviceDto(savedDevice);
}
@PostMapping("/add")
@Operation(summary = "Add device")
public DeviceDto addDevice(@RequestBody DeviceDto deviceDto) {
return deviceService.addDevice(deviceDto);
}
I tried to delete ID in DTO class, adding adnotations to Mapper to ignore ID. Also in swagger ui in the request body give the id value as null or any integer
m.wietecki is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
You are missing autoIncrement="true"
in the liquibase changeSet.createTable.column so the DB expects a value. Try:
<column name="id" type="BIGINT" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
1