Spring Data (liquibase)
Introduction
This page show simple Spring Data JPA repositories and Entities for accessing Liquibase tables:
DATABASECHANGELOG
DATABASECHANGELOGLOCK
Entities
package edu.cou.myapp.entity.liquibase;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* https://www.liquibase.org/documentation/databasechangelog_table.html<br>
* <br>
* There is no primary key on the table. This is to avoid any database-specific restrictions on key lengths. The composite of “id”, “author”, and “filename” is unique across all rows of the table.<br>
*/
@NoArgsConstructor
@AllArgsConstructor
@Data
@Entity
@Table(name = "DATABASECHANGELOG")
public class DatabaseChangelog {
/**
* Identifier.
*/
@EmbeddedId
private DatabaseChangelogId id;
@Column(name = "DATEEXECUTED")
@Temporal(TemporalType.TIMESTAMP)
private Date dateExecuted;
@Column(name = "ORDEREXECUTED")
private Integer orderExecuted;
@Column(name = "EXECTYPE")
private String execType;
@Column(name = "MD5SUM")
private String md5Sum;
@Column(name = "DESCRIPTION")
private String description;
@Column(name = "COMMENTS")
private String comments;
@Column(name = "TAG")
private String tag;
@Column(name = "LIQUIBASE")
private String liquibase;
@Column(name = "CONTEXTS")
private String contexts;
@Column(name = "LABELS")
private String labels;
@Column(name = "DEPLOYMENT_ID")
private String deploymentId;
}
package edu.cou.myapp.entity.liquibase;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* Entity id & DTO.<br>
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@Embeddable
public class DatabaseChangelogId implements Serializable {
/**
*
*/
private static final long serialVersionUID = -3341096236731313707L;
@EqualsAndHashCode.Include
@Column(name = "ID")
private String id;
@EqualsAndHashCode.Include
@Column(name = "AUTHOR")
private String author;
@EqualsAndHashCode.Include
@Column(name = "FILENAME")
private String filename;
}
package edu.cou.myapp.entity.liquibase;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* It represents a record in Liquibase table DATABASECHANGELOGLOCK<br>
* https://www.liquibase.org/documentation/databasechangeloglock_table.html <br>
*
* JPA entity that represents a 'Liquibase lock'.<br>
*/
@Getter
@Entity
@NoArgsConstructor
@Table(name = "DATABASECHANGELOGLOCK")
public class DatabaseChangelogLock {
/** ID of the lock. There is currently only one lock. */
@Id
@Column(name = "ID")
private Integer id;
/**
* Set to "1" if Liquibase is running against this database. Otherwise set to "0".
*/
@Column(name = "LOCKED", nullable = false, updatable = true)
private Integer locked; // NOSONAR
/**
* Date and time that the lock was granted.<br>
* DATETIME
*/
@Column(name = "LOCKGRANTED", nullable = true, updatable = true)
@Temporal(TemporalType.TIMESTAMP)
private Date lockGranted; // Maybe better: java.time.Instant
/**
* Human-readable description of who the lock was granted to.<br>
* VARCHAR(255)
*/
@Column(name = "LOCKEDBY", nullable = true, updatable = true)
private String lockedBy; // NOSONAR
}
Repositories
Release the liquibase lock:
package edu.cou.myapp.repository.liquibase;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import edu.cou.myapp.entity.liquibase.DatabaseChangelogLock;
/**
* Liquibase table "DATABASECHANGELOGLOCK".<br>
* https://www.liquibase.org/documentation/databasechangeloglock_table.html <br>
* <br>
* If Liquibase gets locked, log will show:<br>
* SELECT LOCKED FROM public.databasechangeloglock WHERE ID=1<br>
* <br>
* (+)It can be unlocked with:<br>
* UPDATE DATABASECHANGELOGLOCK SET LOCKED=FALSE, LOCKGRANTED=null, LOCKEDBY=null where ID=1;<br>
* <br>
* (+)Alternatively using Spring Data REST:<br>
* https://sites.google.com/site/pawneecity/sprint-boot/data-rest-spring-boot<br>
* <br>
*/
public interface DatabaseChangelogLockRepository extends
JpaRepository<DatabaseChangelogLock, Integer> {
/**
* Release the liquibase lock.<br>
* WARNING: ONLY if it's locked unexpectedly
*/
@Query(
value = "UPDATE DATABASECHANGELOGLOCK SET LOCKED=false, LOCKGRANTED=null, LOCKEDBY=null WHERE ID=1",
nativeQuery = true)
void releaseLiquibaseLock();
}
package edu.cou.myapp.repository.liquibase;
import org.springframework.data.jpa.repository.JpaRepository;
import edu.cou.myapp.entity.liquibase.DatabaseChangelog;
import edu.cou.myapp.entity.liquibase.DatabaseChangelogId;
/**
* Liquibase table "DATABASECHANGELOG".<br>
* https://www.liquibase.org/documentation/databasechangelog_table.html<br>
*/
public interface DatabaseChangelogRepository extends
JpaRepository<DatabaseChangelog, DatabaseChangelogId> {
}