diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index 696fa5dbf..9cc43fef5 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -3155,6 +3155,13 @@ public class BeanDescriptor implements BeanType { return versionProperty; } + /** + * Return true if this type is tenant aware. + */ + public boolean isMultiTenant() { + return tenant != null; + } + /** * Return the tenant property when multi-tenant partitioning support is used. */ diff --git a/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java b/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java index bc6a5cfe8..8459d8e2d 100644 --- a/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java +++ b/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java @@ -578,6 +578,16 @@ public final class DefaultPersister implements Persister { } BeanDescriptor descriptor = beanDescriptorManager.getBeanDescriptor(beanType); + boolean softDelete = !permanent && descriptor.isSoftDelete(); + if (descriptor.isMultiTenant()) { + // convert to a delete by bean + for (Object id : ids) { + EntityBean bean = descriptor.createEntityBean(); + descriptor.convertSetId(id, bean); + deleteRecurse(bean, transaction, permanent); + } + return ids.size(); + } ArrayList idList = new ArrayList<>(ids.size()); for (Object id : ids) { @@ -585,7 +595,6 @@ public final class DefaultPersister implements Persister { idList.add(descriptor.convertId(id)); } - boolean softDelete = !permanent && descriptor.isSoftDelete(); return delete(descriptor, null, idList, transaction, softDelete); } @@ -595,6 +604,14 @@ public final class DefaultPersister implements Persister { @Override public int delete(Class beanType, Object id, Transaction transaction, boolean permanent) { BeanDescriptor descriptor = beanDescriptorManager.getBeanDescriptor(beanType); + if (descriptor.isMultiTenant()) { + // convert to a delete by bean + EntityBean bean = descriptor.createEntityBean(); + descriptor.convertSetId(id, bean); + delete(bean, transaction, permanent); + return 1; + } + id = descriptor.convertId(id); boolean softDelete = !permanent && descriptor.isSoftDelete(); return delete(descriptor, id, null, transaction, softDelete); diff --git a/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableAssocOne.java b/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableAssocOne.java index 9ccb00aea..bf4339410 100644 --- a/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableAssocOne.java +++ b/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableAssocOne.java @@ -66,15 +66,4 @@ class BindableAssocOne implements Bindable { } } - /** - * Cast to an EntityBean allowing null. - */ - EntityBean castToEntityBean(Object objectValue) { - if (objectValue instanceof EntityBean || objectValue == null) { - return (EntityBean) objectValue; - } else { - throw new IllegalStateException("Bean " + objectValue.getClass() + " is not enhanced?"); - } - } - } diff --git a/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableAssocTenant.java b/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableAssocTenant.java new file mode 100644 index 000000000..eab3678a5 --- /dev/null +++ b/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableAssocTenant.java @@ -0,0 +1,20 @@ +package io.ebeaninternal.server.persist.dmlbind; + +import io.ebean.bean.EntityBean; +import io.ebeaninternal.server.deploy.BeanPropertyAssocOne; + +import java.sql.SQLException; + +class BindableAssocTenant extends BindableAssocOne { + + BindableAssocTenant(BeanPropertyAssocOne assocOne) { + super(assocOne); + } + + @Override + public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException { + + EntityBean assocBean = (EntityBean) assocOne.getValue(bean); + importedId.bind(request, assocBean); + } +} diff --git a/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableProperty.java b/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableProperty.java index bc0840ce2..0d76baf3c 100644 --- a/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableProperty.java +++ b/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableProperty.java @@ -54,15 +54,4 @@ public class BindableProperty implements Bindable { request.bind(value, prop); } - /** - * For compound types bind one of the underlying scalar values for a compound type. - */ - public void dmlBindObject(BindableRequest request, Object bean) throws SQLException { - - Object value = null; - if (bean != null) { - value = prop.getValueObject(bean); - } - request.bind(value, prop); - } } diff --git a/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryVersion.java b/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryVersion.java index e52484d81..abb7f1a20 100644 --- a/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryVersion.java +++ b/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryVersion.java @@ -2,6 +2,7 @@ package io.ebeaninternal.server.persist.dmlbind; import io.ebeaninternal.server.deploy.BeanDescriptor; import io.ebeaninternal.server.deploy.BeanProperty; +import io.ebeaninternal.server.deploy.BeanPropertyAssocOne; /** * Creates a Bindable to support version concurrency where clauses. @@ -36,6 +37,12 @@ public class FactoryVersion { public Bindable createTenantId(BeanDescriptor desc) { BeanProperty tenant = desc.getTenantProperty(); - return (tenant == null) ? null : new BindableProperty(tenant); + if (tenant == null) { + return null; + } else if (tenant instanceof BeanPropertyAssocOne) { + return new BindableAssocTenant((BeanPropertyAssocOne) tenant); + } else { + return new BindableProperty(tenant); + } } } diff --git a/src/test/java/org/multitenant/partition/MultiTenantPartitionTest.java b/src/test/java/org/multitenant/partition/MultiTenantPartitionTest.java index ff007a938..2625266ef 100644 --- a/src/test/java/org/multitenant/partition/MultiTenantPartitionTest.java +++ b/src/test/java/org/multitenant/partition/MultiTenantPartitionTest.java @@ -8,6 +8,7 @@ import org.ebeantest.LoggedSqlCollector; import org.junit.Test; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -54,7 +55,45 @@ public class MultiTenantPartitionTest { assertThat(sql.get(0)).contains("delete from mt_content where id=? and tenant_id=? and version=?"); LoggedSqlCollector.stop(); + } + @Test + public void deleteById() { + + UserContext.set("fred", "ten_2"); + + MtContent content = new MtContent("first title"); + server.save(content); + + LoggedSqlCollector.start(); + server.delete(MtContent.class, content.getId()); + + List sql = LoggedSqlCollector.stop(); + assertThat(sql.get(0)).contains("delete from mt_content where id=? and tenant_id=?"); + } + + @Test + public void deleteByIds() { + + UserContext.set("fred", "ten_2"); + + MtContent a = newContent("title a"); + MtContent b = newContent("title b"); + + + List ids = Arrays.asList(a.getId(), b.getId()); + + LoggedSqlCollector.start(); + server.deleteAll(MtContent.class, ids); + + List sql = LoggedSqlCollector.stop(); + assertThat(sql.get(0)).contains("delete from mt_content where id=? and tenant_id=?"); + } + + private MtContent newContent(String title) { + MtContent content = new MtContent(title); + server.save(content); + return content; }