Skip to content

Deeply Understanding the Controllability of Pointer-Type Fields in GORM ​

Introduction ​

When using GORM for database operations, we often encounter scenarios where precise control over field updates is required. Especially for fields of boolean and string types, how can we ensure that we can correctly update field values to zero values (such as false or empty string) is a common issue. This article will explore in depth the use of pointer-type fields in GORM and how to correctly implement controllable updates of field values.

Boolean type field issue ​

Limitations of non-pointer boolean types ​

go
type Task struct {
    Id          uint
    IsCompleted bool `gorm:"type:tinyint(1)"`
}

When using the above structure, if we want to IsCompleted from true Updated to false, will encounter problems:

go
db.Model(&Task{Id: 1}).Updates(Task{IsCompleted: false})
// Actually, no updates will be executed at all!

This is because GORM ignores zero-value fields by default (false is the zero value of the boolean type), considering that these fields do not need to be updated.

Solution: Use a Boolean pointer ​

go
type Task struct {
    Id          uint
    IsCompleted *bool `gorm:"type:tinyint(1)"`
}

Now we can update it like this:

go
completed := false
db.Model(&Task{Id: 1}).Updates(Task{IsCompleted: &completed})
// Successfully updated IsCompleted to false

By using pointers, we can clearly distinguish between "not updating this field" and "setting this field to the zero value".

Special cases of string-type fields ​

The problem with string pointers ​

go
type Task struct {
	Id           int64   `gorm:"culumn:id;bigint;not null;primary_key;comment:Record Id;"`
	State        uint8   `gorm:"culumn:state;tinyint(1);not null;default:1;"`
	FailedReason *string `gorm:"culumn:failed_reason;size:128;null;"`
}

When we try to update the string pointer field:

go
db.Model(&Task{Id: 1}).Updates(Task{FailedReason: nil})
// May not update in some GORM versions!

Reminder

If the task with task.id 1 fails and the failure reason is updated, if at some point you want to update the value of this field again through the above GORM Updates operation, the operation will not update the in the Task data table failed_reason is NULL!

Solution: use a specific update method UpdateColumn ​

go
db.Model(&Task{Id: 1}).UpdateColumn("failed_reason", nil)

Reminder

Updating via the UpdateColumn method can bypass these zero-value restrictions!

A Deep Understanding of GORM's Update Mechanism ​

GORM's update behavior follows these rules:

  • For non-pointer type fields:

  • Zero values will be ignored (not updated)

  • Non-zero values will be updated.

  • For pointer type fields:

  • nil pointers are ignored (not updated)

  • Non-nil pointers will be updated even if they point to a zero value.

  • Exceptions:

  • Some types (such as string pointers) may have special handling in some GORM versions.

  • Using specific methods (such as UpdateColumn) can bypass these restrictions

best practices ​

  • For fields that require precise control of zero values, use pointer types.

  • Boolean value:*bool

  • String:*string

  • Number:*int,*float64 wait

  • Clarify the update intent

  • Use Select Specify the fields to update

  • For critical updates, consider using UpdateColumn

  • Maintain consistency

  • Use pointer or non-pointer types consistently throughout the project.

  • Explicitly agree on an update strategy within the team.

  • Test verification

  • Write test cases for the scenario of updating a zero value.

  • Verify behavior across different GORM versions

Summary ​

By reasonably using pointer types and correct update methods, we can fully control field update behavior in GORM. The key lies in understanding:

  • Pointer types allow us to distinguish between “no update” and “update to zero value”.

  • Some field types may require special handling.

  • Choosing the correct update method has a decisive impact on the results.

After mastering these techniques, you will be able to control database operations more precisely and avoid unexpected behavior caused by zero-value issues.

Last updated on11/07/2026, 02:16 PM
@fishfinal | @fishfinals | [email protected]