Skip to content

Add a SnapshotGenerator


Implementing Liquibase extensions requires an understanding of Java. You will be creating classes, overriding methods, and working with inheritance hierarchies.

Project Setup

If you have not already created a repository to hold your code, see Your First Extension in the Getting Started guide.


When defining the snapshot logic for a particular DatabaseObject, the interface you are going to implement is liquibase.snapshot.SnapshotGenerator.

Best Practices

Base Class

There is a liquibase.snapshot.jvm.JdbcSnapshotGenerator convenience base class that is used for all the standard DatabaseObject SnapshotGenerators which separates the "create the base object" logic from the "add to an object" logic plus has caching built into it.

Custom Methods

The standard SnapshotGenerators tend to have overridable functions for commonly variable portions of the snapshot logic, so you generally shouldn't override snapshot() itself but more targeted methods instead.


Specifying database-specific functionality is best done with if (database instanceof ExampleDatabase) blocks around the database-specific logic.

Using "instanceof" rather than "equals" allows the logic to apply to any subclasses (variants) of the given database.

Example Code

package com.example.snapshot;

import com.example.database.ExampleDatabase;
import liquibase.database.Database;
import liquibase.snapshot.CachedRow;
import liquibase.snapshot.SnapshotGenerator;
import liquibase.snapshot.jvm.ColumnSnapshotGenerator;
import liquibase.structure.DatabaseObject;
import liquibase.structure.core.Column;

public class ColumnSnapshotGeneratorExample extends ColumnSnapshotGenerator {

    public int getPriority(Class<? extends DatabaseObject> objectType, Database database) {
        if (database instanceof ExampleDatabase) {
            return super.getPriority(objectType, database);
        } else {
            return PRIORITY_NONE;

    public Class<? extends SnapshotGenerator>[] replaces() {
        return new Class[] {

    protected Object readDefaultValue(CachedRow columnMetadataResultSet, Column columnInfo, Database database) {
        if (columnInfo.getType().getTypeName().equalsIgnoreCase("json")) {
            return columnMetadataResultSet.get("default_value_json");
        } else {
            return super.readDefaultValue(columnMetadataResultSet, columnInfo, database);

Last update: April 11, 2023
Created: March 28, 2023