mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#919 - io.ebean package initial
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user