非必需的 1 到 1 映射的 Hibernate 投影/延迟加载
Hibernate Projections / Lazy Loading for non required 1 to 1 Mappings
我有以下 2 个 类(为此 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;
...
...
...
}
我试图在不加载 applicationHomeScreen 的情况下加载 applicationById
不幸的是,延迟加载似乎不起作用。我看过其他 posts,他们建议在 @OneToOne 注释上设置 option=false 标志,但不幸的是,applicationHomeScreen 可以是可选的
我现在正在尝试使用投影,但这对我也不起作用
当我调用下面的方法时
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;
}
我得到堆栈跟踪
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)
任何人都可以推荐一种我可以使用的方法吗
a)在不需要关联的一对一映射中使延迟加载正常工作
b) 让预测工作,这样我就不需要加载任何不需要的子关联
谢谢
达米恩
可选 @OneToOne
关系不能惰性,因为关系的 non-owning 端现在不知道 child 是否存在(可选)- Hibernate 不知道是否要放置一个代理 object 或 null
。有几种解决方法。 link 对一些变通方法有详细的解释
唯一的选择是遵循以下步骤:
将@LazyToOne添加到一对一关联中:
@OneToOne(fetch = FetchType.LAZY, mappedBy = "application")
@Cascade({ CascadeType.ALL })
@JsonIgnore
@LazyToOne(value = LazyToOneOption.NO_PROXY)
private ApplicationHomeScreenVO applicationHomeScreen;
我有以下 2 个 类(为此 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;
...
...
...
}
我试图在不加载 applicationHomeScreen 的情况下加载 applicationById 不幸的是,延迟加载似乎不起作用。我看过其他 posts,他们建议在 @OneToOne 注释上设置 option=false 标志,但不幸的是,applicationHomeScreen 可以是可选的
我现在正在尝试使用投影,但这对我也不起作用
当我调用下面的方法时
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;
}
我得到堆栈跟踪
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)
任何人都可以推荐一种我可以使用的方法吗 a)在不需要关联的一对一映射中使延迟加载正常工作 b) 让预测工作,这样我就不需要加载任何不需要的子关联
谢谢 达米恩
可选 @OneToOne
关系不能惰性,因为关系的 non-owning 端现在不知道 child 是否存在(可选)- Hibernate 不知道是否要放置一个代理 object 或 null
。有几种解决方法。 link 对一些变通方法有详细的解释
唯一的选择是遵循以下步骤:
将@LazyToOne添加到一对一关联中:
@OneToOne(fetch = FetchType.LAZY, mappedBy = "application") @Cascade({ CascadeType.ALL }) @JsonIgnore @LazyToOne(value = LazyToOneOption.NO_PROXY) private ApplicationHomeScreenVO applicationHomeScreen;