#919 - io.ebean package initial

This commit is contained in:
Rob Bygrave
2016-12-11 23:23:22 +13:00
parent 5821dc96b9
commit 971e2dc91b
2134 changed files with 10721 additions and 8652 deletions
@@ -0,0 +1,33 @@
package org.tests.idkeys;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.ECustomId;
import org.avaje.moduuid.ModUUID;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class TestCustomId extends BaseTestCase {
@Test
public void insert() {
ECustomId bean = new ECustomId("fred");
Ebean.save(bean);
assertNotNull(bean.getId());
}
@Test
public void insert_when_hasValue() {
ECustomId bean = new ECustomId("gotId");
String explicitId = ModUUID.newShortId();
bean.setId(explicitId);
Ebean.save(bean);
ECustomId found = Ebean.find(ECustomId.class, explicitId);
assertEquals(found.getName(), bean.getName());
}
}
@@ -0,0 +1,132 @@
package org.tests.idkeys;
import io.ebean.Transaction;
import io.ebean.Platform;
import io.ebean.config.dbplatform.IdType;
import io.ebeaninternal.api.SpiEbeanServer;
import org.tests.idkeys.db.GenKeyIdentity;
import org.tests.idkeys.db.GenKeySequence;
import org.tests.lib.EbeanTestCase;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* Test various key generation strategies.
* <p>
* 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();
if (!IdType.SEQUENCE.equals(idType)) {
// only run this test when SEQUENCE is being used
return;
}
if (server.getDatabasePlatform().getPlatform() == Platform.H2) {
// 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();
}
*/
}
@@ -0,0 +1,39 @@
package org.tests.idkeys;
import org.tests.lib.EbeanTestCase;
import org.tests.model.basic.TOne;
import java.sql.SQLException;
import java.util.List;
/**
* Test lazy loading
*/
public class TestLazyLoad extends EbeanTestCase {
/**
* This test loads just a single property of the Entity AuditLog and later on access
* the description which should force a lazy load of this property
*/
public void testPartialLoad() throws SQLException {
TOne log = new TOne();
log.setName("test partial");
log.setDescription("log");
getServer().save(log);
assertNotNull(log.getId());
List<TOne> logs = getServer().find(TOne.class)
.select("id")
.where().eq("id", log.getId())
.findList();
assertNotNull(logs);
assertEquals(1, logs.size());
TOne logLazy = logs.get(0);
String description = logLazy.getDescription();
assertEquals(log.getDescription(), description);
}
}
@@ -0,0 +1,170 @@
package org.tests.idkeys;
import io.ebean.Transaction;
import io.ebean.bean.EntityBean;
import org.tests.idkeys.db.AuditLog;
import org.tests.lib.EbeanTestCase;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* Test various aspects of the PropertyChangeSupport
*/
public class TestPropertyChangeSupport extends EbeanTestCase implements PropertyChangeListener {
private int nuofEvents = 0;
private List<PropertyChangeEvent> pces = new ArrayList<>();
private PropertyChangeEvent lastPce;
public void propertyChange(PropertyChangeEvent evt) {
nuofEvents++;
lastPce = evt;
pces.add(evt);
}
/**
* Test the core property change functionality
*/
public void testPropertyChange() throws SQLException {
resetEvent();
AuditLog al = new AuditLog();
assertTrue("is EntityBean check", al instanceof EntityBean);
addListener(al, this);
// test if we get property notification about simple property changes
al.setDescription("ABC");
assertNotNull(lastPce);
assertEquals(1, nuofEvents);
assertEquals("description", lastPce.getPropertyName());
assertNull(lastPce.getOldValue());
assertEquals("ABC", lastPce.getNewValue());
al.setDescription("DEF");
assertNotNull(lastPce);
assertEquals(2, nuofEvents);
assertEquals("description", lastPce.getPropertyName());
assertEquals("ABC", lastPce.getOldValue());
assertEquals("DEF", lastPce.getNewValue());
resetEvent();
// test if we get change notification if EBean assigns an id to the bean
getServer().save(al);
assertNotNull(lastPce);
assertEquals("id", lastPce.getPropertyName());
assertNull(lastPce.getOldValue());
assertNotNull(lastPce.getNewValue());
String prevLogDesc = al.getDescription();
resetEvent();
// simulate external change and test if we get change notification when we refresh the entity
Transaction tx = getServer().beginTransaction();
PreparedStatement pstm = tx.getConnection().prepareStatement("update audit_log set description = ? where id = ?");
pstm.setString(1, "GHI");
pstm.setLong(2, al.getId());
int updated = pstm.executeUpdate();
pstm.close();
assertEquals(1, updated);
tx.commit();
assertNull(lastPce);
assertEquals(0, nuofEvents);
getServer().refresh(al);
assertEquals("GHI", al.getDescription());
assertNotNull(lastPce);
assertEquals(1, nuofEvents);
assertEquals("description", lastPce.getPropertyName());
assertEquals(prevLogDesc, lastPce.getOldValue());
assertNotNull("GHI", lastPce.getNewValue());
// check if we fire with the real new value which might be a modified version of what we passed to the set method
resetEvent();
al.setModifiedDescription("MODIFIED_VALUE");
assertNotNull(lastPce);
assertEquals(1, nuofEvents);
assertEquals("modifiedDescription", lastPce.getPropertyName());
assertEquals(null, lastPce.getOldValue());
assertNotNull("_MODIFIED_VALUE_", lastPce.getNewValue());
}
/**
* check if
* <ul>
* <li>updating a lazy loaded property fires two events</li>
* </ul>
*/
public void testPartialLoad() throws SQLException {
AuditLog log = new AuditLog();
log.setDescription("log");
getServer().save(log);
assertNotNull(log.getId());
resetEvent();
List<AuditLog> logs = getServer().find(AuditLog.class)
.where().eq("id", log.getId())
.select("id")
.findList();
assertNotNull(logs);
assertEquals(1, logs.size());
AuditLog logLazy = logs.get(0);
addListener(logLazy, this);
// this will lazy load and update the property
logLazy.setDescription("updated log");
// which should result in one PCE events
assertEquals(1, pces.size());
// test for the acutal update of the value
PropertyChangeEvent propertyChangeEvent = pces.get(0);
assertEquals("description", propertyChangeEvent.getPropertyName());
assertEquals("log", propertyChangeEvent.getOldValue());
assertEquals("updated log", propertyChangeEvent.getNewValue());
}
private void resetEvent() {
lastPce = null;
nuofEvents = 0;
pces.clear();
}
private static void addListener(AuditLog al, PropertyChangeListener listener) {
try {
//Ebean.getBeanState(al).addPropertyChangeListener(listener);
Method apcs = al.getClass().getMethod("addPropertyChangeListener", PropertyChangeListener.class);
apcs.invoke(al, listener);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
@@ -0,0 +1,51 @@
package org.tests.idkeys;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.tests.model.basic.ESimple;
import org.junit.Assert;
import org.junit.Test;
public class TestSimpleIdInsert extends BaseTestCase {
@Test
public void test() {
ESimple e = new ESimple();
e.setName("name");
Ebean.save(e);
Assert.assertNotNull(e.getId());
}
// // This test fails with jdbc drivers that don't
// // support batch insert with getGeneratedKeys
// public void testJdbcBatch() {
//
// GlobalProperties.put("datasource.default", "hsqldb");
// GlobalProperties.put("ebean.classes", ESimple.class.getName());
//
// Transaction transaction = Ebean.beginTransaction();
// try {
// transaction.setBatchMode(true);
// transaction.setLogLevel(LogLevel.SQL);
// ESimple e = new ESimple();
// e.setName("name");
// Ebean.save(e);
//
// ESimple e2 = new ESimple();
// e2.setName("name2");
// Ebean.save(e2);
// transaction.commit();
//
// Assert.assertNotNull(e.getId());
// Assert.assertNotNull(e2.getId());
//
// } finally {
// Ebean.endTransaction();
// }
// }
}
@@ -0,0 +1,41 @@
package org.tests.idkeys.db;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
// Just let Ebean define Identity mechanism for testing across all DB types
//@SequenceGenerator(name = "AD_SEQ_NAME", sequenceName = "AD_SEQ")
public class AuditLog {
@Id
//@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AD_SEQ_NAME")
private Long id;
private String description;
private String modifiedDescription;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getModifiedDescription() {
return modifiedDescription;
}
public void setModifiedDescription(String modifiedDescription) {
this.modifiedDescription = modifiedDescription == null ? null : "_" + modifiedDescription + "_";
}
}
@@ -0,0 +1,31 @@
package org.tests.idkeys.db;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class GenKeyIdentity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String description;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
@@ -0,0 +1,35 @@
package org.tests.idkeys.db;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
@Entity
@SequenceGenerator(name = "SEQ_NAME", sequenceName = GenKeySequence.SEQUENCE_NAME)
public class GenKeySequence {
public final static String SEQUENCE_NAME = "SEQ";
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_NAME")
private Long id;
private String description;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
@@ -0,0 +1,31 @@
package org.tests.idkeys.db;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class GenKeyTable {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
private String description;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}