Change to use enhancement for creating new entity bean instances

This commit is contained in:
Rob Bygrave
2014-04-25 15:54:07 +12:00
parent 75bcbc06e1
commit 14034ffaa0
8 changed files with 43 additions and 33 deletions
@@ -46,7 +46,7 @@ public class CachedBeanDataFromBean {
}
// create a readOnly sharable instance by copying the data
EntityBean sharableBean = desc.createBean();
EntityBean sharableBean = desc.createEntityBean();
BeanProperty idProp = desc.getIdProperty();
if (idProp != null) {
Object v = idProp.getValue(bean);
@@ -62,7 +62,6 @@ import com.avaje.ebeaninternal.server.query.CQueryPlan;
import com.avaje.ebeaninternal.server.query.CQueryPlanStats.Snapshot;
import com.avaje.ebeaninternal.server.query.SplitName;
import com.avaje.ebeaninternal.server.querydefn.OrmQueryDetail;
import com.avaje.ebeaninternal.server.reflect.BeanReflect;
import com.avaje.ebeaninternal.server.text.json.ReadJsonContext;
import com.avaje.ebeaninternal.server.text.json.ReadJsonContext.ReadBeanState;
import com.avaje.ebeaninternal.server.text.json.WriteJsonContext;
@@ -148,12 +147,6 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
*/
private final String baseTable;
/**
* Used to provide mechanism to new EntityBean instances. Generated code
* faster than reflection at this stage.
*/
private final BeanReflect beanReflect;
/**
* Map of BeanProperty Linked so as to preserve order.
*/
@@ -298,6 +291,8 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
*/
private final TypeManager typeManager;
private final EntityBean prototypeEntityBean;
private final IdBinder idBinder;
private String idBinderInLHSSql;
@@ -345,6 +340,8 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
this.typeManager = typeManager;
this.beanType = deploy.getBeanType();
this.prototypeEntityBean = createPrototypeEntityBean(beanType);
this.namedQueries = deploy.getNamedQueries();
this.namedUpdates = deploy.getNamedUpdates();
@@ -373,8 +370,6 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
this.baseTable = InternString.intern(deploy.getBaseTable());
this.beanReflect = deploy.getBeanReflect();
this.autoFetchTunable = EntityType.ORM.equals(entityType) && (beanFinder == null);
// helper object used to derive lists of properties
@@ -434,13 +429,27 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
if (Modifier.isAbstract(beanType.getModifiers())) {
this.idPropertyIndex = -1;
this.versionPropertyIndex = -1;
} else {
EntityBean entityBean = createEntityBean();
EntityBeanIntercept ebi = entityBean._ebean_getIntercept();
EntityBeanIntercept ebi = prototypeEntityBean._ebean_getIntercept();
this.idPropertyIndex = (idProperty == null) ? -1 : ebi.findProperty(idProperty.getName());
this.versionPropertyIndex = (versionProperty == null) ? -1 : ebi.findProperty(versionProperty.getName());
}
}
/**
* Create an entity bean that is used as a prototype/factory to create new instances.
*/
private EntityBean createPrototypeEntityBean(Class<T> beanType) {
if (Modifier.isAbstract(beanType.getModifiers())) {
return null;
}
try {
return (EntityBean) beanType.newInstance();
} catch (Exception e) {
throw new IllegalStateException("Error trying to create the prototypeEntityBean for "+beanType, e);
}
}
private LinkedHashMap<String, BeanProperty> getReverseMap(LinkedHashMap<String, BeanProperty> propMap) {
@@ -1114,21 +1123,11 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
}
/**
* Create an EntityBean.
*/
public EntityBean createBean() {
return createEntityBean();
}
/**
* Creates a new EntityBean without using the creation queue.
* Creates a new EntityBean.
*/
public EntityBean createEntityBean() {
try {
// Note factoryType is used indirectly via beanReflect
return (EntityBean) beanReflect.createEntityBean();
return (EntityBean)prototypeEntityBean._ebean_newInstance();
} catch (Exception ex) {
throw new PersistenceException(ex);
}
@@ -1150,7 +1149,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
}
}
try {
EntityBean eb = createBean();
EntityBean eb = createEntityBean();
convertSetId(id, eb);
@@ -419,7 +419,7 @@ public final class BeanDescriptorCacheHelp<T> {
}
}
EntityBean bean = desc.createBean();
EntityBean bean = desc.createEntityBean();
desc.convertSetId(id, bean);
if (Boolean.TRUE.equals(readOnly)) {
bean._ebean_getIntercept().setReadOnly(true);
@@ -387,7 +387,7 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> {
* value.
*/
public Object createEmbeddedId() {
return getTargetDescriptor().createBean();
return getTargetDescriptor().createEntityBean();
}
/**
@@ -224,8 +224,8 @@ public class InheritInfo {
/**
* Create an EntityBean for this type.
*/
public EntityBean createBean() {
return descriptor.createBean();
public EntityBean createEntityBean() {
return descriptor.createEntityBean();
}
/**
@@ -246,7 +246,7 @@ public final class IdBinderEmbedded implements IdBinder {
public Object readData(DataInput dataInput) throws IOException {
EntityBean embId = idDesc.createBean();
EntityBean embId = idDesc.createEntityBean();
boolean notNull = true;
for (int i = 0; i < props.length; i++) {
@@ -279,7 +279,7 @@ public final class IdBinderEmbedded implements IdBinder {
public Object read(DbReadContext ctx) throws SQLException {
EntityBean embId = idDesc.createBean();
EntityBean embId = idDesc.createEntityBean();
boolean notNull = true;
for (int i = 0; i < props.length; i++) {
@@ -182,7 +182,7 @@ public class SqlTreeNodeBean implements SqlTreeNode {
localType = null;
localDesc = desc;
} else {
localBean = localInfo.createBean();
localBean = localInfo.createEntityBean();
localType = localInfo.getType();
localIdBinder = localInfo.getIdBinder();
localDesc = localInfo.getBeanDescriptor();
@@ -191,7 +191,7 @@ public class SqlTreeNodeBean implements SqlTreeNode {
} else {
localType = null;
localDesc = desc;
localBean = desc.createBean();
localBean = desc.createEntityBean();
localIdBinder = idBinder;
}
@@ -4,8 +4,10 @@ import org.junit.Assert;
import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.BeanState;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.tests.model.basic.MProtectedConstructBean;
public class TestProtectedConstructor extends BaseTestCase {
@@ -22,6 +24,15 @@ public class TestProtectedConstructor extends BaseTestCase {
// Note1 that the enhancement ClassAdapterEntity line 239 makes a default constructor publically accessible
// Note2 the ClassAdpater will call DefaultConstructor.add() to add a default constructor if it doesn't exist
EntityBean entityBean = (EntityBean)bean;
Object newBeanInstance = entityBean._ebean_newInstance();
Assert.assertNotNull(newBeanInstance);
BeanState beanState = Ebean.getBeanState(newBeanInstance);
Assert.assertTrue(beanState.isNew());
Assert.assertNotSame(entityBean, newBeanInstance);
}
}