diff --git a/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java b/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java index 6160691c2..8c0113b1e 100644 --- a/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java +++ b/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java @@ -642,7 +642,7 @@ public final class PersistRequestBean extends PersistRequest implements BeanP * Create and return a new reference bean matching this beans Id value. */ public T createReference() { - return beanDescriptor.createReference(Boolean.FALSE, false, getBeanId(), null); + return beanDescriptor.createReference(getBeanId(), null); } /** diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index 1c34a0783..87161ce55 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -1204,7 +1204,7 @@ public class BeanDescriptor implements BeanType { if (tenant != null && !query.isNativeSql()) { Object tenantId = ebeanServer.currentTenantId(); if (tenantId != null) { - query.where().eq(tenant.getName(), tenantId); + tenant.addTenant(query, tenantId); } } if (isDocStoreOnly()) { @@ -1872,6 +1872,29 @@ public class BeanDescriptor implements BeanType { } } + /** + * Create a non read only reference bean without checking cacheSharableBeans. + */ + @SuppressWarnings("unchecked") + public T createReference(Object id, PersistenceContext pc) { + + try { + EntityBean eb = createEntityBean(); + id = convertSetId(id, eb); + EntityBeanIntercept ebi = eb._ebean_getIntercept(); + ebi.setBeanLoader(ebeanServer); + ebi.setReference(idPropertyIndex); + if (pc != null) { + contextPut(pc, id, eb); + ebi.setPersistenceContext(pc); + } + return (T) eb; + + } catch (Exception ex) { + throw new PersistenceException(ex); + } + } + /** * Return the bean property traversing the object graph and taking into * account inheritance. @@ -2725,7 +2748,7 @@ public class BeanDescriptor implements BeanType { */ public void setTenantId(EntityBean entityBean, Object tenantId) { if (tenant != null) { - tenant.setValue(entityBean, tenantId); + tenant.setTenantValue(entityBean, tenantId); } } diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java b/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java index 05f1d8d70..03b4bb2bd 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java @@ -9,8 +9,10 @@ import io.ebean.config.dbplatform.DbEncryptFunction; import io.ebean.config.dbplatform.DbPlatformType; import io.ebean.plugin.Property; import io.ebean.text.StringParser; +import io.ebean.util.SplitName; import io.ebean.util.StringHelper; import io.ebeaninternal.api.SpiExpressionRequest; +import io.ebeaninternal.api.SpiQuery; import io.ebeaninternal.server.core.InternString; import io.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty; import io.ebeaninternal.server.deploy.generatedproperty.GeneratedWhenCreated; @@ -20,7 +22,6 @@ import io.ebeaninternal.server.el.ElPropertyChainBuilder; import io.ebeaninternal.server.el.ElPropertyValue; import io.ebeaninternal.server.properties.BeanPropertyGetter; import io.ebeaninternal.server.properties.BeanPropertySetter; -import io.ebean.util.SplitName; import io.ebeaninternal.server.query.SqlBeanLoad; import io.ebeaninternal.server.query.SqlJoinType; import io.ebeaninternal.server.text.json.ReadJson; @@ -720,6 +721,20 @@ public class BeanProperty implements ElPropertyValue, Property { bean._ebean_getIntercept().setChangedProperty(propertyIndex); } + /** + * Add the tenantId predicate to the query. + */ + public void addTenant(SpiQuery query, Object tenantId) { + query.where().eq(name, tenantId); + } + + /** + * Set the tenantId onto the bean. + */ + public void setTenantValue(EntityBean entityBean, Object tenantId) { + setValue(entityBean, tenantId); + } + /** * Set the value of the property without interception or * PropertyChangeSupport. diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java index 7c2f3cc08..c58c658db 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java @@ -967,7 +967,7 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc { if (isManyToMany()) { if (liveBean == null) { // add new relationship (Map not allowed here) - liveVal.addBean(targetDescriptor.createReference(Boolean.FALSE, false, id, null)); + liveVal.addBean(targetDescriptor.createReference(id, null)); } } else { diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java index df0a7b8ae..584f0fbfb 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java @@ -8,6 +8,7 @@ import io.ebean.ValuePair; import io.ebean.bean.EntityBean; import io.ebean.bean.PersistenceContext; import io.ebean.util.SplitName; +import io.ebeaninternal.api.SpiQuery; import io.ebeaninternal.server.cache.CacheChangeSet; import io.ebeaninternal.server.cache.CachedBeanData; import io.ebeaninternal.server.core.DefaultSqlUpdate; @@ -419,7 +420,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc { // cacheData is the id value, maybe already in persistence context Object assocBean = targetDescriptor.contextGet(context, cacheData); if (assocBean == null) { - assocBean = targetDescriptor.createReference(Boolean.FALSE, false, cacheData, context); + assocBean = targetDescriptor.createReference(cacheData, context); } setValue(bean, assocBean); } @@ -605,6 +606,16 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc { return localHelp.read(ctx); } + public void addTenant(SpiQuery query, Object tenantId) { + T refBean = targetDescriptor.createReference(tenantId, null); + query.where().eq(name, refBean); + } + + public void setTenantValue(EntityBean entityBean, Object tenantId) { + T refBean = targetDescriptor.createReference(tenantId, null); + setValue(entityBean, refBean); + } + @Override public void setValue(EntityBean bean, Object value) { super.setValue(bean, value); diff --git a/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java b/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java index b67093ec3..8c849e76b 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java +++ b/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java @@ -207,6 +207,9 @@ public class DeployBeanPropertyLists { } else { nonManys.add(prop); + if (prop.isTenantId()) { + tenant = prop; + } if (prop instanceof BeanPropertyAssocOne) { BeanPropertyAssocOne assocOne = (BeanPropertyAssocOne) prop; if (prop.isEmbedded()) { @@ -227,8 +230,6 @@ public class DeployBeanPropertyLists { } } else if (prop.isDraftDirty()) { draftDirty = prop; - } else if (prop.isTenantId()) { - tenant = prop; } if (!prop.isAggregation()) { baseScalar.add(prop); diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocOnes.java b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocOnes.java index 872d97c0d..7c614dee6 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocOnes.java +++ b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocOnes.java @@ -2,6 +2,7 @@ package io.ebeaninternal.server.deploy.parse; import io.ebean.annotation.DbForeignKey; import io.ebean.annotation.FetchPreference; +import io.ebean.annotation.TenantId; import io.ebean.annotation.Where; import io.ebean.config.NamingConvention; import io.ebeaninternal.server.deploy.BeanDescriptorManager; @@ -63,6 +64,9 @@ public class AnnotationAssocOnes extends AnnotationParser { ManyToOne manyToOne = get(prop, ManyToOne.class); if (manyToOne != null) { readManyToOne(manyToOne, prop); + if (get(prop, TenantId.class) != null) { + prop.setTenantId(); + } } OneToOne oneToOne = get(prop, OneToOne.class); if (oneToOne != null) { diff --git a/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java b/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java index 48538582a..bc6a5cfe8 100644 --- a/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java +++ b/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java @@ -1138,7 +1138,7 @@ public final class DefaultPersister implements Persister { // convert into a list of reference objects and perform delete by object List refList = new ArrayList<>(childIds.size()); for (Object id : childIds) { - refList.add(targetDesc.createReference(null, false, id, null)); + refList.add(targetDesc.createReference(id, null)); } deleteList(refList, t, softDelete); diff --git a/src/test/java/io/ebeaninternal/server/deploy/BeanDescriptorTest.java b/src/test/java/io/ebeaninternal/server/deploy/BeanDescriptorTest.java index 795ffe6f4..fa9762127 100644 --- a/src/test/java/io/ebeaninternal/server/deploy/BeanDescriptorTest.java +++ b/src/test/java/io/ebeaninternal/server/deploy/BeanDescriptorTest.java @@ -3,9 +3,9 @@ package io.ebeaninternal.server.deploy; import io.ebean.BaseTestCase; import io.ebean.bean.EntityBean; import io.ebean.plugin.Property; +import org.junit.Test; import org.tests.model.basic.Customer; import org.tests.model.basic.Order; -import org.junit.Test; import java.util.Collection; @@ -35,6 +35,9 @@ public class BeanDescriptorTest extends BaseTestCase { Customer bean = customerDesc.createReference(Boolean.FALSE, false, 42, null); assertThat(server().getBeanState(bean).isReadOnly()).isFalse(); + + bean = customerDesc.createReference(42, null); + assertThat(server().getBeanState(bean).isReadOnly()).isFalse(); } @Test