How to force OpenJPA (1.2.2) to eager load a @Many

2019-07-19 06:46发布

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

}

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 ?

标签: java jpa openjpa
1条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-07-19 07:00

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.

查看更多
登录 后发表回答