package com.avaje.tests.idkeys;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.avaje.ebean.Transaction;
import com.avaje.ebean.config.dbplatform.IdType;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import com.avaje.tests.idkeys.db.GenKeyIdentity;
import com.avaje.tests.idkeys.db.GenKeySequence;
import com.avaje.tests.lib.EbeanTestCase;
/**
* Test various key generation strategies.
*
* Notice: The strategy {@link javax.persistence.GenerationType#AUTO} is not easy to test as it is database dependent
* which of the strategies will be used.
*/
public class TestGeneratedKeys extends EbeanTestCase
{
/**
* Test key generation using a sequence.
* This should increment the used sequence by one.
* EBean should construct a select statement which uses the configured sequence to get the next value
* <p/>
* Notice: Actually, this test depends on H2 as used database as we are going to fetch the current value from the sequence
*/
public void testSequence() throws SQLException
{
SpiEbeanServer server = (SpiEbeanServer)getServer();
IdType idType = server.getDatabasePlatform().getDbIdentity().getIdType();
String platformName = server.getDatabasePlatform().getName();
if (!IdType.SEQUENCE.equals(idType)){
// only run this test when SEQUENCE is being used
return;
}
if (!"h2".equals(platformName)){
// readSequenceValue is H2 specific
return;
}
Transaction tx = getServer().beginTransaction();
long sequenceStart = readSequenceValue(tx, GenKeySequence.SEQUENCE_NAME);
GenKeySequence al = new GenKeySequence();
al.setDescription("my description");
getServer().save(al);
long sequenceCurrent = readSequenceValue(tx, GenKeySequence.SEQUENCE_NAME);
assertNotNull(al.getId());
assertFalse("sequence advanced", sequenceStart == sequenceCurrent);
assertEquals("sequence advanced by 20", sequenceStart + 20, sequenceCurrent);
}
private long readSequenceValue(Transaction tx, String sequence) throws SQLException
{
Statement stm = null;
try
{
stm = tx.getConnection().createStatement();
ResultSet rs = stm.executeQuery("select currval('" + sequence + "')");
rs.next();
return rs.getLong(1);
}
finally
{
if (stm != null)
{
try
{
stm.close();
}
catch (SQLException e)
{
;
}
}
}
}
/**
* This test just checks if a generated value has been passed back from the database.
* EBean should simply fetch the generated key after inserting.
*/
public void testIdentity() throws SQLException
{
SpiEbeanServer server = (SpiEbeanServer)getServer();
IdType idType = server.getDatabasePlatform().getDbIdentity().getIdType();
if (!IdType.IDENTITY.equals(idType)){
// only run this test when SEQUENCE is being used
return;
}
Transaction tx = getServer().beginTransaction();
GenKeyIdentity al = new GenKeyIdentity();
al.setDescription("my description");
getServer().save(al);
// For JDBC batching we won't get the id until after
// the batch has been flushed explicitly or via commit
//assertNotNull(al.getId());
tx.commit();
assertNotNull(al.getId());
}
/**
* This should use the next value using max(col)+1 on the table
*
* AFAIK this is not supported by EBean yet
public void testTable() throws SQLException
{
EbeanServer server = Ebean.getServer(null);
Transaction tx = server.beginTransaction();
GenKeyTable al = new GenKeyTable();
al.setDescription("my description");
server.save(al);
assertNotNull(al.getId());
assertEquals(0L, al.getId().longValue());
al = new GenKeyTable();
al.setDescription("my description - another object");
server.save(al);
assertNotNull(al.getId());
assertEquals(1L, al.getId().longValue());
tx.commit();
}
*/
}