我认输了。我不明白,这能有多难?
我有两个实体User
and Group
,具有多对多关系。Group
管理关系。所以在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;
那么对于User
我创建实体如下:
@Entity
@Table(name = "USERS", catalog = "", schema = "GROUPADMIN")
public class User {
...
@ManyToMany(mappedBy="users")
private Set<Group> groups;
然后在我的支持豆中,实际上是@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
会使用惰性绑定,所以我将其更改为fetch = FetchType.EAGER
(但这并不重要)。这样做之后,事情真的变得很奇怪......
此时 EL 开始抱怨 id 属性不存在"#{g.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
on a HashSet
代理,而不是在Group
?
所以我很好奇我到底参与了什么g
我从获得的属性<h:dataTable>
,我尝试简单地使用输出它<h:outputText value="#{g}"/>
...结果真的很有趣...
What g
打印出来的不仅仅是其中的一个元素Set<Group>
,但实际上是集合本身,它与之前显示的异常相匹配......这更能表明 API 或集成中的错误?
所以基本上看起来有几件事被破坏了,尽管我怀疑这一切都与同一问题有关。
请注意,我使用了基本的现成 TomEE,最新版本,没有定制(也没有 JPA 的增强器)。