You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by "Jo Desmet (JIRA)" <ji...@apache.org> on 2014/11/24 10:24:12 UTC
[jira] [Updated] (OPENJPA-2546) OpenJPA using ManyToMany does not
work with Set
[ https://issues.apache.org/jira/browse/OPENJPA-2546?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Jo Desmet updated OPENJPA-2546:
-------------------------------
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:
{code:java}
@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;
{code}
Then for User I create the entity something as follows:
{code:java}
@Entity
@Table(name = "USERS", catalog = "", schema = "GROUPADMIN")
public class User {
...
@ManyToMany(mappedBy="users")
private Set<Group> groups;
{code}
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
{code:html}
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>
{code:java}
For those interested in the tables:
{code:sql}
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)
);
{code}
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).
{code}
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)
{code}
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.
was:
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:
{code:java}
@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;
{code}
Then for User I create the entity something as follows:
{code:java}
@Entity
@Table(name = "USERS", catalog = "", schema = "GROUPADMIN")
public class User {
...
@ManyToMany(mappedBy="users")
private Set<Group> groups;
{code}
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
{code:html}
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>
{code:java}
For those interested in the tables:
{code:sql}
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)
);
{code}
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).
{code}
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)
{code}
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.
> OpenJPA using ManyToMany does not work with Set<xxx>
> ----------------------------------------------------
>
> Key: OPENJPA-2546
> URL: https://issues.apache.org/jira/browse/OPENJPA-2546
> Project: OpenJPA
> Issue Type: Bug
> Components: instrumentation, jpa
> Affects Versions: 2.4.0
> Environment: Running as part of TomEE 1.7.1
> Reporter: Jo Desmet
> Labels: @ManyToMany, bidirectional
>
> 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:
> {code:java}
> @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;
> {code}
> Then for User I create the entity something as follows:
> {code:java}
> @Entity
> @Table(name = "USERS", catalog = "", schema = "GROUPADMIN")
> public class User {
> ...
> @ManyToMany(mappedBy="users")
> private Set<Group> groups;
> {code}
> 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
> {code:html}
> 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>
> {code:java}
> For those interested in the tables:
> {code:sql}
> 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)
> );
> {code}
> 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).
> {code}
> 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)
> {code}
> 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.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)