我尝试将应用程序从 Hibernate 迁移到 OpenJPA,并且“突然”不再获取 @OneToMany 关系。
情况可以总结如下:我有两个 Entity Member和Username。一个成员可以有多个用户名。Ii 在数据库中由两个表(成员和用户名)实现,其中用户名表包含成员 ID 作为外键列。
这导致实体:
@Table(name="member")
public class Member implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(unique=true, nullable=false)
private int id;
...
@OneToMany(mappedBy="member")
private List<Username> usernames;
...
}
和
@Entity
@Table(name="username")
public class Username implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(insertable=false, updatable=false, unique=true, nullable=false)
private int id;
//bi-directional many-to-one association to Member
@ManyToOne
@JoinColumn(name="member_id", nullable=false)
private Member member;
...
两个实体类都具有用于属性的公共 setter 和 getter 以及默认构造函数。(我尝试了一种“即插即用”的方法,并在 Eclipse 中从现有数据库自动创建了这些类)。
这些类在persistence.xml文件中声明
<persistence-unit name="...">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>allwi.data.jpa.Member</class>
<class>allwi.data.jpa.Username</class>
我正在使用 VAADIN 框架的 JPAContainer 来加载数据。使用休眠加载成员数据并隐式加载用户名效果很好。切换到 OpenJPA 后,用户名集合为空。当我在成员对象上调用getUsernames()时,我仍然返回 null 并且没有执行额外的提取。我将日志级别增加到 TRACE 并看到只执行了对成员表的简单 SQL 提取。
我也已经尝试添加Fetch=EAGER和Cascade=ALL没有区别。
我必须犯一个愚蠢的错误,因为似乎我是唯一遇到这个问题的人。如前所述,我使用的是VAADIN JPAContainer,即基本上我对实体管理器的创建没有太大影响。
我错过了什么?
非常感谢
编辑 1
改进了代码片段并添加了对 DB 设计的一些解释。
编辑 2
我检查了该行为是否与 JPAContainer 相关。因此,我手动创建了 EntityManager:
EntityManagerFactory emf = Persistence.createEntityManagerFactory(...);
EntityManager em = emf.createEntityManager();
Member m = em.find(Member.class, 14661667);
结果是一样的:我从 Member 表的列中获取数据,我还从 Member 中的 @ManyToOne 关系中获取数据——比如状态——但不是 @OneToMany 关系的集合。
编辑 3
我正在使用 PostgreSQL 作为数据库。