Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA is eager loading FetchType.LAZY child collections

I've seen several similar questions with 0 good answers.

This should be very simple. I'm using Java JPA and I want to load a List of child entities sometimes but not all the time. Unfortunately, JPA doesn't seem to be listening to me when I say to fetch it lazily. I've made 100% certain that there's nowhere in my code where the childEntities attribute is being accessed in any way. However, all the child entities are still getting loaded immediately upon my JPA.em().find(..) call. This is how I declare the relationship with annotations.

@Entity
@Table(name = "parentEntities")
public class ParentEntity implements Serializable {
    ....
    @OneToMany(mappedBy = "entityPropertyName", fetch = FetchType.LAZY)
    public List<ChildEntity> childEntities;
    ...
}

And this is how I load the parent entity:

ParentEntity parentEntity = JPA.em().find(ParentEntity.class, id);

Additionally, I was hoping to sometimes eager fetch this collection and be able to dynamically tell JPA when to do so. That's step 2 though. Step 1 is just to get this working right.

like image 359
Cameron Askew Avatar asked Jul 27 '13 22:07

Cameron Askew


1 Answers

I have done in this way. Please refer this, it will be working excellently overthere too:

@Entity
@Table(name = "member_information")
    public class MemberInformation  implements Serilizable{

     @OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE},optional = false)
        private MemberInformationDetails memberInformationDetailsId;


     @LazyCollection(LazyCollectionOption.TRUE)
        @OneToMany(mappedBy = "memberInformationId", cascade = CascadeType.ALL)
        private Collection<AccountOpening> accountOpeningCollection;


    }

Use @OneToOne(fetch = FetchType.LAZY....) for one to one mapping and for collection use @LazyCollection(LazyCollectionOption.TRUE).

@Entity
@Table(name = "member_info_details")
public class MemberInformationDetails implements Serializable{

@OneToOne(mappedBy = "memberInformationDetailsId")
    private MemberInformation memberInformationId;

.......//getter and setters

}


@Entity
@Table(name = "account_opening")
public class AccountOpening  implements Serializable {

 @JoinColumn(name = "member_information_id", referencedColumnName = "id", nullable = false)
    @ManyToOne(optional = false)
    private MemberInformation memberInformationId;

..........//getters and setters

}

When you want to access the collection ,merge before and get the object:

@Stateless
public class MemberInformationFacade{
..............
  public MemberInformation getMemberWithMemberDetails(MemberInformation m) {
        m = getEntityManager().merge(m);
        try {
            m.getMemberInformationDetailsId().getId();


            m.getMemberInformationDetailsId().accountOpeningCollection().size();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return m;
    }

}
like image 177
Rajesh Avatar answered Oct 21 '22 09:10

Rajesh