如何强制OpenJPA(1.2.2)急切加载@ManyToOne组合主键?

时间:2011-09-01 16:00:30

标签: java jpa openjpa

我有两个实体使用组合的primarky键:

@Entity
@IdClass(APK.class)
public class A {
    @Id
    Integer pk1;

    @Id
    Integer pk2;

    @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER,mappedBy="a")
    List<B> b = new ArrayList<B>();

    String name;
    ...
}

@Entity
@IdClass(BPK.class)
public class B {
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumns({
        @JoinColumn(name = "pk1", referencedColumnName = "pk1"),
        @JoinColumn(name = "pk2", referencedColumnName = "pk2")
    })
    @Id 
    private A a;

    @Id
    Integer additional_key_part;

}

当我加载“A”类时,列表被正确加载,问题是,当我加载“B”类时它不起作用。

“B”类将正确使用Join with A,但只会填充A的PK字段(pk1,pk2),而不是其余部分。

当实体发送到没有事务的客户端时,真正的问题就出现了,因此不能进行延迟加载。似乎唯一有效的方法是在关闭事务之前调用a.getName()或其他东西来启动延迟加载,但这似乎不是正确的方法。

那么,如何确保实体及其所有子代都已加载?

1 个答案:

答案 0 :(得分:1)

尝试将注释更改为以下内容:

@Entity
@IdClass(ClassBPK.class)
public class ClassB {

    @Id
    private Integer pk1;
    @Id
    private Integer pk2;

    @ManyToOne(fetch = FetchType.EAGER)
    @PrimaryKeyJoinColumns({
        @PrimaryKeyJoinColumn(name = "pk1", referencedColumnName = "pk1"),
        @PrimaryKeyJoinColumn(name = "pk2", referencedColumnName = "pk2")
    })
    private ClassA a;

    @Id
    private Integer pk3;

    //...
}

我使用Derby和DAO草案快速检查OpenJPA 1.2.2:

logger.debug("Pre find");
ClassB b = bDAOBean.findById(bId);
logger.debug("Post find");
logger.debug("A's name: {}", b.getA().getName());

我得到了:

[DEBUG] Pre find 
[INFO ] openjpa.Runtime - Starting OpenJPA 1.2.2 {main}
// ... Here comes SQL from loading the entity
[DEBUG] Post-find
[DEBUG] A's name: nameA11

最后两个日志行之间没有OpenJPA日志,因此证明整个ClassA都是急切加载的。