I have the following 2 classes (trimmed down for this post)
public class ApplicationVO implements Serializable {
/**
*
*/
private static final long serialVersionUID = -3314933694797958587L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Integer id;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "application")
@Cascade({ CascadeType.ALL })
@JsonIgnore
private ApplicationHomeScreenVO applicationHomeScreen;
...
...
...
}
public class ApplicationHomeScreenVO implements Serializable {
/**
*
*/
private static final long serialVersionUID = -9158898930601867545L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
@JsonProperty("id")
private Integer id;
@OneToOne(fetch = FetchType.LAZY)
@Cascade({ CascadeType.SAVE_UPDATE })
@JoinColumn(name="application_id")
@JsonProperty("application")
protected ApplicationVO application;
...
...
...
}
I am trying to load an applicationById wuthout loading the applicationHomeScreen Unfortunately the lazy loading doesnt seem to be working. I have looked at other posts and they recommend setting the option=false flag on the @OneToOne annotation but unfortunately, applicationHomeScreen can be optional
I am now trying to use projections but that is not working either for me either
When I call the following method
public ApplicationVO findApplicationById(Integer applicationId) {
Criteria criteria = currentSession().createCriteria(ApplicationVO.class);
criteria.add(Restrictions.eq("id", applicationId));
criteria.setProjection(Projections.projectionList()
.add(Projections.property("applicationHomeScreen"), "applicationHomeScreen"))
.setResultTransformer(Transformers.aliasToBean(ApplicationVO.class));
ApplicationVO applicationVO = (ApplicationVO) criteria.uniqueResult();
return applicationVO;
}
I get the stack trace
java.lang.ArrayIndexOutOfBoundsException: 0
at org.hibernate.loader.criteria.CriteriaLoader.getResultRow(CriteriaLoader.java:168)
at org.hibernate.loader.criteria.CriteriaLoader.getResultColumnOrRow(CriteriaLoader.java:148)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:754)
at org.hibernate.loader.Loader.processResultSet(Loader.java:953)
at org.hibernate.loader.Loader.doQuery(Loader.java:921)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355)
at org.hibernate.loader.Loader.doList(Loader.java:2554)
at org.hibernate.loader.Loader.doList(Loader.java:2540)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370)
at org.hibernate.loader.Loader.list(Loader.java:2365)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:126)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1682)
at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:380)
at org.hibernate.internal.CriteriaImpl.uniqueResult(CriteriaImpl.java:402)
at com.dao.database.impl.ApplicationDAOImpl.findApplicationById(ApplicationDAOImpl.java:349)
Can anyone recommend an approach I can use to either a) get lazy loading working properly for one to one mappings where the association is not required b) get projections working so I dont need to load any child associations if they are not needed
Thank you Damien
The only option is to follow these steps:
Add @LazyToOne to the one-to-one association:
@OneToOne(fetch = FetchType.LAZY, mappedBy = "application")
@Cascade({ CascadeType.ALL })
@JsonIgnore
@LazyToOne(value = LazyToOneOption.NO_PROXY)
private ApplicationHomeScreenVO applicationHomeScreen;
Configure bytecode enhancement
Optional @OneToOne
relationships cannot be lazy because the non-owning side of the relationship does not now whether the child exists(optional) - Hibernate doesn't know whether to put a proxy object or null
. There are several workarounds for this. This link has detailed explanation on some workarounds
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With