diff --git a/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataFromBean.java b/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataFromBean.java index c6b6797c2..37dc2e208 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataFromBean.java +++ b/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataFromBean.java @@ -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); diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java index be314287b..813dce2c5 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java @@ -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 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 implements MetaBeanInfo { */ private final TypeManager typeManager; + private final EntityBean prototypeEntityBean; + private final IdBinder idBinder; private String idBinderInLHSSql; @@ -345,6 +340,8 @@ public class BeanDescriptor 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 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 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 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 getReverseMap(LinkedHashMap propMap) { @@ -1114,21 +1123,11 @@ public class BeanDescriptor 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 implements MetaBeanInfo { } } try { - EntityBean eb = createBean(); + EntityBean eb = createEntityBean(); convertSetId(id, eb); diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorCacheHelp.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorCacheHelp.java index a60ce3e41..eaac6c5b9 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorCacheHelp.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorCacheHelp.java @@ -419,7 +419,7 @@ public final class BeanDescriptorCacheHelp { } } - EntityBean bean = desc.createBean(); + EntityBean bean = desc.createEntityBean(); desc.convertSetId(id, bean); if (Boolean.TRUE.equals(readOnly)) { bean._ebean_getIntercept().setReadOnly(true); diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java index 102dcddc5..b5d41b30d 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java @@ -387,7 +387,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc { * value. */ public Object createEmbeddedId() { - return getTargetDescriptor().createBean(); + return getTargetDescriptor().createEntityBean(); } /** diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/InheritInfo.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/InheritInfo.java index 3d61685b3..765f08aac 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/InheritInfo.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/InheritInfo.java @@ -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(); } /** diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/id/IdBinderEmbedded.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/id/IdBinderEmbedded.java index fed1f003c..ddb3d9e25 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/id/IdBinderEmbedded.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/id/IdBinderEmbedded.java @@ -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++) { diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java index 42d87158a..09bea9ed1 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java @@ -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; } diff --git a/src/test/java/com/avaje/tests/contructor/TestProtectedConstructor.java b/src/test/java/com/avaje/tests/contructor/TestProtectedConstructor.java index c1ad1c224..4983a7140 100644 --- a/src/test/java/com/avaje/tests/contructor/TestProtectedConstructor.java +++ b/src/test/java/com/avaje/tests/contructor/TestProtectedConstructor.java @@ -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); + } }