#1973 - L2Cache, Inheritance and Lazy-Loading loads the parent Class not the Child

This commit is contained in:
rob bygrave
2020-03-10 22:52:13 +13:00
parent 91a327a5e7
commit 48abc73e50
12 changed files with 291 additions and 21 deletions
@@ -0,0 +1,19 @@
package org.tests.inheritance.cache;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
@Entity
public class CIAddress extends CIBaseModel {
@ManyToOne
public CIStreetParent street;
public CIStreetParent getStreet() {
return street;
}
public void setStreet(CIStreetParent street) {
this.street = street;
}
}
@@ -0,0 +1,23 @@
package org.tests.inheritance.cache;
import io.ebean.Model;
import io.ebean.annotation.Cache;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
@Cache(enableQueryCache=true)
@MappedSuperclass
public abstract class CIBaseModel extends Model {
@Id
protected long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
@@ -0,0 +1,19 @@
package org.tests.inheritance.cache;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue(value="1")
public class CICustomer extends CICustomerParent {
public String notes;
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
}
@@ -0,0 +1,27 @@
package org.tests.inheritance.cache;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.ManyToOne;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "dtype", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue(value = "0")
public class CICustomerParent extends CIBaseModel {
@ManyToOne
protected CIAddress address;
public CIAddress getAddress() {
return address;
}
public void setAddress(CIAddress adress) {
this.address = adress;
}
}
+21
View File
@@ -0,0 +1,21 @@
package org.tests.inheritance.cache;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "street")
@DiscriminatorValue(value = "1")
public class CIStreet extends CIStreetParent {
protected String number;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
@@ -0,0 +1,25 @@
package org.tests.inheritance.cache;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "dtype", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue(value = "0")
public class CIStreetParent extends CIBaseModel {
protected String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -0,0 +1,63 @@
package org.tests.inheritance.cache;
import io.ebean.DB;
import org.junit.Assert;
import org.junit.Test;
public class TestInheritCacheRefLoad {
@Test
public void findWithRefToInheritStreetBean_expect_correctStreetType() {
DB.find(CICustomerParent.class).delete();
DB.find(CIAddress.class).delete();
DB.find(CIStreet.class).delete();
//=========================================================================
// 1 - Create Data (Customer(dtype 1) -> Address(no dtype) -> Street(dtype 1)
//=========================================================================
CIStreet street = new CIStreet();
street.save();
CIAddress address = new CIAddress();
address.setStreet(street);
address.save();
CICustomer customer = new CICustomer();
customer.setAddress(address);
customer.save();
//=========================================================================
// 2 - Read Data (no Cache Hit)
//=========================================================================
Class streetClass = reloadCustomer(customer, false); //returns Street -> OK
Assert.assertEquals("org.tests.inheritance.cache.CIStreet", streetClass.getName());
streetClass = reloadCustomer(customer, false); //returns Street -> OK
Assert.assertEquals("org.tests.inheritance.cache.CIStreet", streetClass.getName());
//=========================================================================
// 3 - Read Data (L2-Cache Hit)
//=========================================================================
streetClass = reloadCustomer(customer, true); //returns Street -> OK
Assert.assertEquals("org.tests.inheritance.cache.CIStreet", streetClass.getName());
streetClass = reloadCustomer(customer, true); //returns StreetParent -> NOT OK
Assert.assertEquals("org.tests.inheritance.cache.CIStreet", streetClass.getName());
}
public Class reloadCustomer(CICustomer customer, boolean l2Cache) {
// Load Customer via Query, L2Cache on/off
CICustomer customerReloaded =
DB.find(CICustomer.class)
.where().eq("id", customer.getId())
.setUseCache(l2Cache)
.findOne();
//Access Street by lazy Loading
Class streetClassLazyLoaded = customerReloaded.getAddress().getStreet().getClass();
//Show Cache Hits
System.out.println("Class of Street (Cache on: " + l2Cache + "): " + streetClassLazyLoaded + " | Cache Hit: " + DB.getDefault().getServerCacheManager().getQueryCache(streetClassLazyLoaded).getStatistics(false).getHitCount());
return streetClassLazyLoaded;
}
}
@@ -49,8 +49,7 @@ public class TestInheritanceRefCache extends BaseTestCase {
assertThat(gotRef).isInstanceOf(CInhRef.class);
assertThat(gotRef.getRef()).isInstanceOf(CInhOne.class);
sql = LoggedSqlCollector.stop();
assertThat(sql).hasSize(1);
assertSql(sql.get(0)).contains("from cinh_root");
assertThat(sql).hasSize(0);
// fetch again - both from cache