Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,9 @@ public interface SpiBeanType {
* or removals from the collection.
*/
boolean isToManyDirty(EntityBean bean);

/**
* returns the ID of the bean.
*/
Object getId(EntityBean bean);
}
Original file line number Diff line number Diff line change
Expand Up @@ -311,9 +311,11 @@ private void deleted(Object id) {
deleteSet = new HashSet<>();
}
deleteSet.add(id);
remove(id);
}

private boolean isDeleted(EntityBean bean) {
return deleteSet != null && deleteSet.contains(rootType);
}
/**
* Add the dirty beans to the list.
*/
Expand All @@ -325,7 +327,12 @@ void dirtyBeans(SpiBeanTypeManager manager, List<Object> list) {
if (value == null) continue;
}
EntityBean bean = (EntityBean) value;
if (bean._ebean_getIntercept().isDirty() || beanType.isToManyDirty(bean)) {
boolean deleted = false;
if (deleteSet != null) {
Object id = beanType.getId(bean);
deleted = id != null && deleteSet.contains(id);
}
if (!deleted && bean._ebean_getIntercept().isDirty() || beanType.isToManyDirty(bean)) {
list.add(value);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@


import io.ebean.Database;
import io.ebean.DatabaseBuilder;
import io.ebean.DatabaseFactory;
import io.ebean.Transaction;
import io.ebean.DatabaseBuilder;
import io.ebean.config.DatabaseConfig;
import io.ebean.event.BeanDeleteIdRequest;
import io.ebean.event.BeanPersistAdapter;
import io.ebean.event.BeanPersistController;
import io.ebean.event.BeanPersistRequest;
import io.ebean.test.LoggedSql;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.EBasicVer;
import org.tests.model.basic.UTDetail;
Expand Down Expand Up @@ -132,15 +134,124 @@ public void testInsertUpdateDelete_given_stopPersistingAdapter() {
assertThat(stopPersistingAdapter.methodsCalled).containsExactly("preDeleteById");
stopPersistingAdapter.methodsCalled.clear();

db.deleteAll(EBasicVer.class, Arrays.asList(22,23,24));
db.deleteAll(EBasicVer.class, Arrays.asList(22, 23, 24));
assertThat(stopPersistingAdapter.methodsCalled).hasSize(3);
assertThat(stopPersistingAdapter.methodsCalled).containsExactly("preDeleteById", "preDeleteById", "preDeleteById");
stopPersistingAdapter.methodsCalled.clear();

db.shutdown();
}

private Database getDatabase(PersistAdapter persistAdapter) {
@Test
public void testCascade() {
Database db = getDatabase(new BeanPersistAdapter() {
@Override
public boolean isRegisterFor(Class<?> cls) {
return UTMaster.class == cls;
}

@Override
public boolean preDelete(BeanPersistRequest<?> request) {
return false;
}
});
Integer id;
UTMaster master = new UTMaster();
master.addDetail(new UTDetail());
db.save(master);
id = master.getId();

master = db.find(UTMaster.class, id);
assertThat(master.getDetails()).hasSize(1);

try (Transaction txn = db.beginTransaction()) {
txn.setBatchMode(true);
db.delete(master);
txn.commit();
}

master = db.find(UTMaster.class, id);
assertThat(master).isNotNull();
// CHECKME: Deleting of master was denied by the PersistListener
// What about detail? Is this intended, that it will be deleted?
assertThat(master.getDetails()).hasSize(0);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHECKME:
Can you tell me if the PersistController is intended to protect a bean from deletion? If so, then I would expect that if the deletion process was prevented by UtMaster, its details wouldn't be deleted.

But if you say the PersistController only takes care of the physical persistence, then that would be OK (although perhaps this should be explicitly mentioned again in the documentation for preInsert/Update/Delete).


}

@Test
public void testInsertUpdateDelete_with_LazyLoad() {

Database db = getDatabase(new BeanPersistAdapter() {

@Override
public boolean isRegisterFor(Class<?> cls) {
return EBasicVer.class == cls;
}

@Override
public boolean preInsert(BeanPersistRequest<?> request) {
assertThat(((EBasicVer) request.bean()).getDescription()).isEqualTo("MyDescription");
return true;
}

@Override
public boolean preUpdate(BeanPersistRequest<?> request) {
assertThat(((EBasicVer) request.bean()).getDescription()).isEqualTo("MyDescription");
return true;
}

@Override
public boolean preDelete(BeanPersistRequest<?> request) {
assertThat(((EBasicVer) request.bean()).getDescription()).isEqualTo("MyDescription");
return true;
}
});
Integer id;
try (Transaction txn = db.beginTransaction()) {
txn.setBatchMode(true);
EBasicVer bean = new EBasicVer("testController");
bean.setDescription("MyDescription");

db.save(bean);
txn.commit();
id = bean.getId();
}


try (Transaction txn = db.beginTransaction()) {
txn.setBatchMode(true);
EBasicVer bean = db.find(EBasicVer.class).setUseCache(false).select("name").setId(id).findOne();
bean.setName("otherName");

db.save(bean);

txn.commitAndContinue();

EBasicVer bean2 = db.find(EBasicVer.class).setUseCache(false).select("name").setId(id).findOne();
assertThat(bean2).isSameAs(bean);
}

try (Transaction txn = db.beginTransaction()) {
txn.setBatchMode(true);
EBasicVer bean = db.find(EBasicVer.class).setUseCache(false).select("name").setId(id).findOne();

db.delete(bean);
txn.commitAndContinue();
System.out.println(txn);
}
/*
db.update(bean);

db.delete(bean);

db.delete(EBasicVer.class, 22);

db.deleteAll(EBasicVer.class, Arrays.asList(22,23,24));
*/
db.shutdown();
}

private Database getDatabase(BeanPersistController persistAdapter) {
DatabaseBuilder config = new DatabaseConfig();
config.setName("h2ebasicver");
config.loadFromProperties();
Expand Down Expand Up @@ -194,12 +305,12 @@ public boolean preUpdate(BeanPersistRequest<?> request) {

Object bean = request.bean();
if (bean instanceof UTDetail) {
UTDetail detail = (UTDetail)bean;
UTDetail detail = (UTDetail) bean;
// invoke lazy loading ... which invoke the flush of the jdbc batch
detail.setQty(42);
}
if (bean instanceof UTMaster) {
UTMaster master = (UTMaster)bean;
UTMaster master = (UTMaster) bean;
UTMaster.Journal journal = master.getJournal();
if (journal == null) {
journal = new UTMaster.Journal();
Expand Down