Skip to content

Instantly share code, notes, and snippets.

@DanyelMorales
Created April 19, 2018 17:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DanyelMorales/a3389e7ecda0e5b9adf7adddb09b002e to your computer and use it in GitHub Desktop.
Save DanyelMorales/a3389e7ecda0e5b9adf7adddb09b002e to your computer and use it in GitHub Desktop.
Junit Rule to save ORACLE SEQUENCES
class FooTest {
/**
* Sequence saving
*/
public static SequenceJunitRule sequences = new SequenceJunitRule();
/**
* Restore the sequences on Class DIE.
*/
@AfterClass
public static void tearDownClass() {
if (sequences.isConfigured() && !sequences.validateOnce()) {
sequences.restoreSequences();
}
}
}
package YOUR_PACK;
import java.util.ArrayList;
import java.util.HashMap;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.junit.rules.ExternalResource;
/**
* JUNIT Rule to preserve ORACLE SEQUENCES
*
* This RULE can be used for each test cases using @Rule or as @ClassRule, it's
* possible to use this rule as a single POJO too.
* @author Daniel Vera
*/
public class SequenceJunitRule extends ExternalResource {
private final HashMap<String, String> sequenceBuffer =
new HashMap<String, String>();
private final ArrayList<String> sequenceName = new ArrayList<String>();
private Configuration config;
private String ddldefmode = "create";
private Session temporalSession;
private SessionFactory temporalFactory;
private boolean saveOnce = false;
private boolean isAlreadySaved = false;
/**
* For static tear downs it's wise to set this flag as true.
*
* @param val
* true if we need to execute the after and before rules just one
* time. Otherwise for each test case will be invoked the before
* and after methods.
*/
public SequenceJunitRule isOnce(Boolean val) {
this.saveOnce = val;
return this;
}
/**
* @param config
* Configuration from the factory of Rules, the config will
* handle
* the configuration for hibernate.
*/
public SequenceJunitRule setConfiguration(Configuration config) {
config.setProperty(AvailableSettings.HBM2DDL_AUTO, "validate");
this.config = config;
temporalFactory = config.buildSessionFactory();
temporalSession = temporalFactory.openSession();
return this;
}
/**
* @param ddldefmode
* Default mode for ddl operations on hibernate
*/
public SequenceJunitRule setDDLMode(String ddldefmode) {
this.ddldefmode = ddldefmode;
return this;
}
/**
* @param name
* Collection of existing sequence names
*/
public SequenceJunitRule addSequence(ArrayList<String> name) {
this.sequenceName.addAll(name);
return this;
}
/**
* @param name
* Sequence name to be saved
*/
public SequenceJunitRule addSequence(String name) {
this.sequenceName.add(name);
return this;
}
/**
* @return true if the the once flag is not turned on and at the same time
* the sequences are not already saved.
*/
public boolean validateOnce() {
if (this.saveOnce && this.isAlreadySaved) {
return false;
}
return true;
}
/**
* @return the sequence container
*/
public ArrayList<String> getSequence() {
return this.sequenceName;
}
/**
* @return the sequence buffer used to store values
*/
public HashMap<String, String> getSequenceBuffer() {
return this.sequenceBuffer;
}
/**
* Restore the sequences stored in buffer.
*/
public SequenceJunitRule restoreSequences() {
this.verifySession();
for (String sequence : this.sequenceName) {
if (!this.sequenceBuffer.containsKey(sequence)) {
continue;
}
String val = this.sequenceBuffer.get(sequence);
this.restoreSequence(sequence, val, this.temporalSession);
}
temporalSession.close();
return this;
}
/**
* Create the sequences backup before hibernate drop operations.
*/
private SequenceJunitRule backupSequences(Session tmp) {
this.sequenceBuffer.clear();
for (String sequence : this.sequenceName) {
System.out.println("SAVING SEQUENCE: " + sequence);
this.backupSequence(sequence, tmp);
}
return this;
}
/**
* Verify if the current session factory has a session open. Other wise the
* session is open and assigned to the temporalSession flag.
*/
public void verifySession() {
if (!this.temporalSession.isOpen()) {
this.temporalSession = this.temporalFactory.openSession();
}
}
/**
* @param seqname
* Sequence name to be saved
* @param session
*/
public SequenceJunitRule backupSequence(String seqname, Session session) {
if (seqname == null || seqname.equals("")) {
return null;
}
String sqquery =
String.format("select %s.nextval as num from dual", seqname);
Query query = session.createSQLQuery(sqquery);
String result = query.uniqueResult() + "";
this.sequenceBuffer.put(seqname, result + "");
return this;
}
/**
* Restore the sequence
*
* @param seqname
* sequence name to be restored
* @param seqval
* Sequence value to be injected
*/
public SequenceJunitRule restoreSequence(String seqname, String seqval,
Session session) {
String drop = "DROP SEQUENCE %s";
String create =
"CREATE SEQUENCE %s START WITH %s INCREMENT BY 1 MINVALUE 0 NOCACHE ";
Query q = session.createSQLQuery(String.format(drop, seqname));
q.executeUpdate();
Query q2 =
session.createSQLQuery(String.format(create, seqname, seqval));
q2.executeUpdate();
System.out.println("RESTORING SEQUENCE: " + seqname + " value: "
+ seqval);
return this;
}
/**
* @return true if the required configurations are setted otherwise false.
*/
public boolean isConfigured() {
if (this.ddldefmode == null || this.config == null
|| this.temporalSession == null
|| this.sequenceName.size() == 0) {
return false;
}
return true;
}
/**
* Before any test case Backup the sequences on the container.
*/
@Override
public void before() throws Throwable {
if (!isConfigured() || !validateOnce()) {
return;
}
this.backupSequences(this.temporalSession);
config.setProperty(AvailableSettings.HBM2DDL_AUTO, ddldefmode);
this.isAlreadySaved = true;
}
/**
* After a test case, restore the sequences.
*/
@Override
protected void after() {
if (!isConfigured() || !validateOnce()) {
return;
}
this.restoreSequences();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment