mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-12 22:41:35 +00:00
#2376 - When Lazy load of soft deleted bean - javax.persistence.EntityNotFoundException: Bean not found during lazy load or refresh. id[*] type[class *]
This commit is contained in:
1 parent
b262c2e19d
commit
3865fc8ffd
5 files changed
+71
-16
No files matched your search
@@ -175,14 +175,12 @@ final class DefaultBeanLoader {
|
|||||||
// need a new PersistenceContext for REFRESH
|
// need a new PersistenceContext for REFRESH
|
||||||
pc = null;
|
pc = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
BeanDescriptor<?> desc = server.descriptor(bean.getClass());
|
BeanDescriptor<?> desc = server.descriptor(bean.getClass());
|
||||||
if (EntityType.EMBEDDED == desc.entityType()) {
|
if (EntityType.EMBEDDED == desc.entityType()) {
|
||||||
// lazy loading on an embedded bean property
|
// lazy loading on an embedded bean property
|
||||||
EntityBean embeddedOwner = (EntityBean) ebi.getEmbeddedOwner();
|
EntityBean embeddedOwner = (EntityBean) ebi.getEmbeddedOwner();
|
||||||
refreshBeanInternal(embeddedOwner, mode, ebi.getEmbeddedOwnerIndex());
|
refreshBeanInternal(embeddedOwner, mode, ebi.getEmbeddedOwnerIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
Object id = desc.getId(bean);
|
Object id = desc.getId(bean);
|
||||||
if (pc == null) {
|
if (pc == null) {
|
||||||
// a reference with no existing persistenceContext
|
// a reference with no existing persistenceContext
|
||||||
@@ -202,17 +200,16 @@ final class DefaultBeanLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SpiQuery<?> query = server.createQuery(desc.type());
|
SpiQuery<?> query = server.createQuery(desc.type());
|
||||||
query.setLazyLoadProperty(ebi.getLazyLoadProperty());
|
query.setLazyLoadProperty(ebi.getLazyLoadProperty());
|
||||||
if (draft) {
|
if (draft) {
|
||||||
query.asDraft();
|
query.asDraft();
|
||||||
|
} else {
|
||||||
|
query.setIncludeSoftDeletes();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (embeddedOwnerIndex > -1) {
|
if (embeddedOwnerIndex > -1) {
|
||||||
query.select(ebi.getProperty(embeddedOwnerIndex));
|
query.select(ebi.getProperty(embeddedOwnerIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't collect AutoTune usage profiling information
|
// don't collect AutoTune usage profiling information
|
||||||
// as we just copy the data out of these fetched beans
|
// as we just copy the data out of these fetched beans
|
||||||
// and put the data into the original bean
|
// and put the data into the original bean
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.tests.cache.personinfo;
|
package org.tests.cache.personinfo;
|
||||||
|
|
||||||
import io.ebean.annotation.Cache;
|
import io.ebean.annotation.Cache;
|
||||||
|
import io.ebean.annotation.SoftDelete;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
@@ -16,6 +17,9 @@ public class PersonCacheInfo {
|
|||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
@SoftDelete
|
||||||
|
boolean deleted;
|
||||||
|
|
||||||
public PersonCacheInfo(String personId, String name) {
|
public PersonCacheInfo(String personId, String name) {
|
||||||
this.personId = personId;
|
this.personId = personId;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@@ -36,4 +40,13 @@ public class PersonCacheInfo {
|
|||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean deleted() {
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PersonCacheInfo deleted(boolean deleted) {
|
||||||
|
this.deleted = deleted;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -21,15 +21,12 @@ public class PersonCacheTests {
|
|||||||
|
|
||||||
private final List<Object> ids = Arrays.asList("E001", "E002", "E003");
|
private final List<Object> ids = Arrays.asList("E001", "E002", "E003");
|
||||||
|
|
||||||
private ServerCache beanCacheInfo = DB.getDefault().cacheManager().beanCache(PersonCacheInfo.class);
|
private final ServerCache beanCacheInfo = DB.getDefault().cacheManager().beanCache(PersonCacheInfo.class);
|
||||||
private ServerCache beanCacheEmail = DB.getDefault().cacheManager().beanCache(PersonCacheEmail.class);
|
private final ServerCache beanCacheEmail = DB.getDefault().cacheManager().beanCache(PersonCacheEmail.class);
|
||||||
|
private final ServerCacheRegion region = DB.getDefault().cacheManager().region("email");
|
||||||
private ServerCacheRegion region = DB.getDefault().cacheManager().region("email");
|
|
||||||
|
|
||||||
private void insert(int id, String email) {
|
private void insert(int id, String email) {
|
||||||
|
|
||||||
PersonCacheInfo person = new PersonCacheInfo("P00" + id, "P00" + id);
|
PersonCacheInfo person = new PersonCacheInfo("P00" + id, "P00" + id);
|
||||||
|
|
||||||
PersonCacheEmail personEmail = new PersonCacheEmail("E00" + id, email);
|
PersonCacheEmail personEmail = new PersonCacheEmail("E00" + id, email);
|
||||||
personEmail.setPersonInfo(person);
|
personEmail.setPersonInfo(person);
|
||||||
|
|
||||||
@@ -38,7 +35,6 @@ public class PersonCacheTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addTestData() {
|
private void addTestData() {
|
||||||
|
|
||||||
insert(1, "testA");
|
insert(1, "testA");
|
||||||
insert(2, "testB");
|
insert(2, "testB");
|
||||||
insert(3, "testC");
|
insert(3, "testC");
|
||||||
|
|||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
package org.tests.cache.personinfo;
|
||||||
|
|
||||||
|
import io.ebean.DB;
|
||||||
|
import io.ebean.test.LoggedSql;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class TestCacheSoftDeleteLazyLoad {
|
||||||
|
|
||||||
|
private final String personEmailId = "SDLL-Email-01";
|
||||||
|
private final String personId = "SDLL-Person-01";
|
||||||
|
|
||||||
|
void setup(){
|
||||||
|
PersonCacheInfo person = new PersonCacheInfo(personId , "Hello");
|
||||||
|
PersonCacheEmail personEmail = new PersonCacheEmail(personEmailId, "hello@foo.com");
|
||||||
|
personEmail.setPersonInfo(person);
|
||||||
|
DB.save(person);
|
||||||
|
DB.save(personEmail);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void softDeleteReferencedBean_when_lazyLoad_expect() {
|
||||||
|
setup();
|
||||||
|
// load cache
|
||||||
|
DB.find(PersonCacheEmail.class, personEmailId);
|
||||||
|
|
||||||
|
// soft delete our bean referenced by email
|
||||||
|
PersonCacheInfo info = DB.find(PersonCacheInfo.class, personId);
|
||||||
|
DB.delete(info);
|
||||||
|
|
||||||
|
// load from cache (still references a now soft deleted bean)
|
||||||
|
PersonCacheEmail email2 = DB.find(PersonCacheEmail.class, personEmailId);
|
||||||
|
assert email2 != null;
|
||||||
|
|
||||||
|
LoggedSql.start();
|
||||||
|
PersonCacheInfo personInfo = email2.getPersonInfo();
|
||||||
|
assertThat(personInfo).isNotNull();
|
||||||
|
assertThat(personInfo.deleted()).isTrue(); // lazy load includes soft deletes
|
||||||
|
|
||||||
|
List<String> sql = LoggedSql.stop();
|
||||||
|
assertThat(sql).hasSize(1);
|
||||||
|
assertThat(sql.get(0))
|
||||||
|
.contains(" from person_cache_info t0 where t0.person_id = ?")
|
||||||
|
.doesNotContain("and t0.deleted =");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -79,11 +79,11 @@
|
|||||||
<logger name="io.ebean.docker" level="TRACE"/>
|
<logger name="io.ebean.docker" level="TRACE"/>
|
||||||
<!-- <logger name="io.ebean.DDL" level="DEBUG"/>-->
|
<!-- <logger name="io.ebean.DDL" level="DEBUG"/>-->
|
||||||
|
|
||||||
<!-- <logger name="io.ebean.SQL" level="TRACE"/>-->
|
<logger name="io.ebean.SQL" level="TRACE"/>
|
||||||
<!-- <logger name="io.ebean.TXN" level="TRACE"/>-->
|
<logger name="io.ebean.TXN" level="TRACE"/>
|
||||||
<!-- <logger name="io.ebean.SUM" level="TRACE"/>-->
|
<logger name="io.ebean.SUM" level="TRACE"/>
|
||||||
|
|
||||||
<!-- <logger name="io.ebean.cache" level="TRACE"/>-->
|
<logger name="io.ebean.cache" level="TRACE"/>
|
||||||
<!-- <logger name="io.ebean.cache.REGION" level="TRACE"/>-->
|
<!-- <logger name="io.ebean.cache.REGION" level="TRACE"/>-->
|
||||||
<!-- <logger name="io.ebean.cache.TABLEMOD" level="TRACE"/>-->
|
<!-- <logger name="io.ebean.cache.TABLEMOD" level="TRACE"/>-->
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user