@DbArray collection doesn't work like other persisted collections

55 views
Skip to first unread message

André Camilo

unread,
Nov 18, 2019, 2:20:13 PM11/18/19
to Ebean ORM
I've noticed an inconsistency between @DbArray collections and other persisted collections (@OneToMany, @ManyToMany).

With the entity (I used the WithInitialisedCollectionsTest from ebean-agent):

@Entity
public class WithInitialisedCollections extends BaseEntity {

    @OneToMany(cascade = CascadeType.PERSIST)
  List<Contact> contacts = new ArrayList<>();

  @DbArray
  Set<String> dbArray = new HashSet<>();

  public List<Contact> getContacts() {
    return contacts;
  }

  public void setContacts(List<Contact> contacts) {
    this.contacts = contacts;
  }

  public Set<String> getDbArray() {
    return dbArray;
  }

  public void setDbArray(Set<String> dbArray) {
    this.dbArray = dbArray;
  }
}


The following test fails:

  @Test
  public void test() {

    WithInitialisedCollections bean = new WithInitialisedCollections();
    assertNotNull(bean);

    EntityBean eb = (EntityBean)bean;
    String[] props = eb._ebean_getPropertyNames();

    assertEquals("contacts", props[0]);
    assertEquals("dbArray", props[1]);

    Object val5 = eb._ebean_getField(0);
    Object val9 = eb._ebean_getField(1);
    assertNull(val5);
    assertNull(val9);

    assertNotNull(bean.getContacts());
    assertNotNull(bean.getDbArray());

  }


Because val9 (internal dbArray value) is not null, the initialization was not removed. (and I believed the getter does not garantee to return an instance of collection like the "contacts" collection)

Is this inconsistency on purpose?

Rob Bygrave

unread,
Nov 18, 2019, 3:03:40 PM11/18/19
to ebean@googlegroups
Where does the test fail?

--

---
You received this message because you are subscribed to the Google Groups "Ebean ORM" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ebean+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ebean/549bfa65-27a4-4063-8ebc-4c3e8d4058db%40googlegroups.com.

André Camilo

unread,
Nov 19, 2019, 5:53:30 AM11/19/19
to Ebean ORM
Fails in assertNull(val9).

PS: I don't consider this a bug, I'm just asking if this behavior is intentional or not.
To unsubscribe from this group and stop receiving emails from it, send an email to eb...@googlegroups.com.

Rob Bygrave

unread,
Nov 19, 2019, 7:24:10 AM11/19/19
to ebean@googlegroups
Right so ... 

DbArray ... is treated like a scalar type and does in fact map internally to "ScalarType".  This includes it's enhancement treatment - as you observe it doesn't get the special treatment that OneToMany and ManyToMany get. 

Yes OneToMany and ManyToMany get special treatment for enhancement as "collections" that doesn't apply to DbArray.  Enhancement for them removes any initialisation of them from the bytecode and then always ensures that the collections are initialised on demand.  We do this to ensure we get the appropriate listening for removals for orphanRemoval and M2M + performance.

So yes, that isn't a bug per say.

We could do something similar for DbArray for performance reasons (only initialise the collection on demand like OneToMany & ManyToMany).

Does that make sense?

Cheers, Rob.
 

To unsubscribe from this group and stop receiving emails from it, send an email to ebean+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ebean/60eaa3d1-95c2-439a-a4c4-87b9860be735%40googlegroups.com.

André Camilo

unread,
Nov 19, 2019, 8:15:20 AM11/19/19
to eb...@googlegroups.com
Let me share where I got problems.

I had a collection @OneToMany in an entity, but refactored to use @DbArray. Then all my tests started failing because I never had to concern about collection initialization before.

This is the problem with the 2 approaches not being consistent. 

I understand the fundamental difference between @OneToMany/ManyToMany and @DbArray, but I think the idea of the ORM is to abstract this differences. 

So I personally prefer it to be consistent.

You received this message because you are subscribed to a topic in the Google Groups "Ebean ORM" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ebean/rKQp17GTCJs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ebean+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ebean/CAC%3Dts-F6%3DCLgXdnqrCXBVchn9Z5z084G4mWaMbApohC4WO_q4Q%40mail.gmail.com.

Rob Bygrave

unread,
Nov 19, 2019, 8:22:37 AM11/19/19
to ebean@googlegroups
> Then all my tests started failing because I never had to concern about collection initialization before.

I'd be keen to see what tests started failing means.  What do these tests look like, what do they assert etc.

André Camilo

unread,
Nov 19, 2019, 8:43:44 AM11/19/19
to Ebean ORM
@Entity
public class Role extends DomainObject {
    @DbArray
    private Set<String> permissions;

    public Set<String> getPermissions() {
        return Collections.unmodifiableSet(permissions);
    }

    public void addPermissions(String... permissions) {
        for (String permission : permissions) {
            this.permissions.add(permission);
        }
    }
}

Some simplified test:

    @Test
    public void testFindWithPermission() {
        Role role1 = new Role();
        role1.addPermissions("contact:write:2344", "contact:write:2343");

        RolesRepository repository = new RolesRepository();
        repository.save(role1);

        List<Role> rolesFound = repository.findWithPermission("contact:write:2344");
        assertThat(rolesFound, containsAnyOrder(hasProperty("id", is(role1.getId()));
    }

This tests will fail in addPermission with NPE because the collection was not initialized, but if collection where @ManyToMany (with an Permission entity) this would fail because the collection was initialized.

--

---
You received this message because you are subscribed to a topic in the Google Groups "Ebean ORM" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ebean/rKQp17GTCJs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to eb...@googlegroups.com.

--

---
You received this message because you are subscribed to the Google Groups "Ebean ORM" group.
To unsubscribe from this group and stop receiving emails from it, send an email to eb...@googlegroups.com.

Rob Bygrave

unread,
Nov 19, 2019, 5:23:05 PM11/19/19
to ebean@googlegroups
    @DbArray
    private Set<String> permissions;

Yes I see.  

Yes, have a null problem there with DbArray (that we don't with OneToMany etc) ...  yes I can see that is confusing and inconsistent so yes lets fix that (fix the enhancement of DbArray to work like OneToMany and ensure the DbArray collection is always initialised / never null to calling code).



Cheers, Rob.


To unsubscribe from this group and stop receiving emails from it, send an email to ebean+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ebean/aefde17b-32c3-4a0a-8983-f506fa21ee1d%40googlegroups.com.

André Camilo

unread,
Nov 20, 2019, 9:57:46 AM11/20/19
to eb...@googlegroups.com
Thanks Rob for the quick response and quick fix :)

To unsubscribe from this group and all its topics, send an email to ebean+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ebean/CAC%3Dts-EUGtjuwp_oNWbDSEjzj87ksr-O9XRgabsNFhiE0vU5GA%40mail.gmail.com.

Rob Bygrave

unread,
Sep 29, 2022, 6:11:43 AM9/29/22
to Ebean ORM
Linking to an ongoing discussion on how DbArray is potentially not supporting database null value due to this change - https://github.com/ebean-orm/ebean/discussions/2844
Reply all
Reply to author
Forward
0 new messages