开发者

How to force OpenJPA (1.2.2) to eager load a @ManyToOne combined primary key?

开发者 https://www.devze.com 2023-04-01 16:52 出处:网络
i\'ve got two Entities with combinded primarky keys: @Entity @IdClass(APK.class) public class A { @Id Integer pk1;

i've got two Entities with combinded primarky keys:

@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 Ar开发者_高级运维rayList<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;

}

When i load the "A" class, the List is correctly loaded eagerly, the problem is, it does not work when i load the "B" class.

The "B" class will correctly use an Join with A, but only the PK fields of A will be populated (pk1, pk2), not the rest.

The real problem comes when the entity is send to a client which has no transaction, so no lazy loading possible. The only thing that seemed to work is to call a.getName() or something to start the lazy loading before closing the transaction, but this seems not really the correct way.

So, how to make sure the entity and all its childs are loaded ?


Try changing the annotations to the following:

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

    //...
}

I run a quick check on OpenJPA 1.2.2 with Derby with a draft DAO class:

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

and I got:

[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

There are no OpenJPA logs between the last two log lines, so it proves the whole ClassA was eagerly loaded.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号