使用ManyToMany的TomEE + OpenJPA不起作用

时间:2014-11-23 21:21:41

标签: java jsf java-ee jpa

我正在撒谎。我不明白,它有多难?

我有两个实体UserGroup,有很多关系。 Group管理这种关系。所以在Group我有:

@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;

然后对于User,我按如下方式创建实体:

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

然后在我的支持bean中,实际上是@Named("registry"),我将对检索到的user的引用存储为具有相同名称的属性。

然后我在我的JSF中使用那个支持bean

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>

对于那些对表感兴趣的人:

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)
);

首先注意到的是,组似乎是空的,不是空的,而是空的(通过调试等验证)。所以我理解默认情况下@ManyToMany会使用Lazy绑定,所以我将其更改为fetch = FetchType.EAGER(并不是说这应该重要)。这样做后,事情真的很奇怪......

此时EL开始抱怨"#{g.id}"上的id属性不存在:

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)

为什么要尝试在id代理上检索属性HashSet,而不是Group

所以我很好奇我从g得到的<h:dataTable>属性,我尝试使用<h:outputText value="#{g}"/>输出它...结果真的很有趣..

打印出来的g不仅仅是Set<Group>中的一个元素,而且实际上是集合本身,它与之前显示的异常相匹配......这更像是一个指示API或集成中的错误?

所以基本上看起来好像有几件事情被破坏了,虽然我怀疑这一切都与同一个问题有关。

请注意,我使用了基本的现成TomEE,最新版本,没有自定义(JPA也没有增强器)。

1 个答案:

答案 0 :(得分:0)

为什么它应该有效:JSR 338: JavaTM Persistence 2.1.

错误提交:Jira Issue OpenJPA-2546(请对此问题进行投票决定。)

解决方法:将Set<T>替换为List<T>作为解决方法。