Uploaded image for project: 'OpenJPA'
  1. OpenJPA
  2. OPENJPA-2546

OpenJPA using ManyToMany does not work with Set<xxx>

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 2.4.0
    • None
    • instrumentation, jpa
    • Running as part of TomEE 1.7.1

    Description

      Copying my own posting from StackOverflow.com

      I have two Entities User and Group, having a many to many relationship. Group manages the relationship. So in Group I have:

      @Entity 
      @Table(name = "GROUPS", catalog = "", schema = "GROUPADMIN")
      public class Group {
        ...
        @ManyToMany
        @JoinTable(
          name = "GROUP_USERS",
          joinColumns = {@JoinColumn(name = "GROUP_ID")},
          inverseJoinColumns = {@JoinColumn(name = "USER_ID")}
        )
        private Set<User> users;
      

      Then for User I create the entity something as follows:

      @Entity 
      @Table(name = "USERS", catalog = "", schema = "GROUPADMIN")
      public class User {
        ...
        @ManyToMany(mappedBy="users")
        private Set<Group> groups;
      

      Then in my backing bean, actually a @Named("registry"), I store a reference to a retrieved user as a property with the same name.

      Then I use that backing bean royally in my JSF

      Hello <h:outputLabel value="#{registry.user.firstName}"/>
      <h:panelGroup>
        <h:dataTable value="#{registry.user.groups}" var="g">
          <f:facet name="header">Properties List</f:facet>
          <h:column>
            <f:facet name="header">Group</f:facet>
            <h:outputText value="#{g.id}"/>
          </h:column>
        </h:dataTable>
      </h:panelGroup>
      

      For those interested in the tables:

      create table "GROUPADMIN".GROUPS
      (
        ID VARCHAR(15) not null primary key
      );
      create table "GROUPADMIN".USERS
      (
        ID VARCHAR(50) not null primary key,
        PASSWORD VARCHAR(50),
        FIRST_NAME VARCHAR(50),
        LAST_NAME VARCHAR(50)
      );
      create table "GROUPADMIN".GROUP_USERS
      (
        GROUP_ID VARCHAR(15) not null,
        USER_ID VARCHAR(50) not null,
        primary key (GROUP_ID, USER_ID)
      );
      

      Depending on how (lazy vs Eager) and when I run it, the result would be always wrong, but sometimes different:

      • sometimes complaining that property 'id' does not exist, like example below,
      • sometimes the returned set was Empty (not null, but zero size).
      Caused by:
      javax.el.PropertyNotFoundException - Property 'id' not found on type org.apache.openjpa.util.java$util$HashSet$proxy
      at javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:266)
      

      So me being curious what I actually got into that g attribute I got from the <h:dataTable>, I tried to output it simply using

      <h:outputText value="#{g}"/>

      What g printed out was not just one element out of the Set<Group>, but was actually the collection itself, which matches the earlier shown exception ...

      One important clue is that the problem is resolved once I replace the datatype from Set<Xxx> to List<Xxx>. With that change, everything started working as expected.

      However Logically wise I do need it as a Set, and the JSR documentation seems to support that.

      Attachments

        Activity

          People

            Unassigned Unassigned
            jo_desmet@yahoo.com Jo Desmet
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: