我遇到了hibernate和延迟加载对象的问题。 基本上我想加载一个具有急切加载字段的类,而不加载子类的惰性字段
参加以下QuestionVO课程
@Entity
@Table(name = "question")
public class QuestionVO extends BaseDAOVO implements Serializable {
/**
*
*/
private static final long serialVersionUID = -5867047752936216092L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Integer id;
@Column(name = "questionText", unique = false, nullable = false, length = 4000)
@Size(min = 3, max = 4000)
@Pattern(regexp = MobileAppsRegexConstants.GENERAL_ALLOWED_CHARCHTERS, message = "Question Text Not valid.")
private String questionText;
@ManyToOne(fetch = FetchType.EAGER)
@Cascade({ CascadeType.SAVE_UPDATE })
@JoinColumn(name = "MENU_STYLE_ID", nullable = true)
private MenuStyleVO menuStyle;
}
采取以下MenuStyleVO类
@Entity
@Table(name = "menu_style")
public class MenuStyleVO extends BaseDAOVO implements Serializable{
/**
*
*/
private static final long serialVersionUID = 3697798179195096156L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Integer id;
@Column(name = "menuStyleName", unique = false, nullable = false, length = 200)
private String menuStyleName;
@Column(name = "menuTemplate", unique = false, nullable = false, length = 200)
private String menuTemplate;
@OneToOne(fetch = FetchType.LAZY, optional=false)
@Cascade({ CascadeType.SAVE_UPDATE })
@JoinColumn(name="logo_id")
@JsonProperty("logo")
private ApplicationImageVO logo;
}
这个ApplicationImageVO类
@Entity
@Table(name = "application_image")
public class ApplicationImageVO extends BaseDAOVO implements Serializable {
/**
*
*/
private static final long serialVersionUID = -9158898930601867545L;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "image1242x2208")
@Cascade({ CascadeType.ALL })
@JsonIgnore
private SubmissionLauncherImagesVO launcherImage1242x2208;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "image1536x2048")
@Cascade({ CascadeType.ALL })
@JsonIgnore
private SubmissionLauncherImagesVO launcherImage1536x2048;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "image2048x1536")
@Cascade({ CascadeType.ALL })
@JsonIgnore
private SubmissionLauncherImagesVO launcherImage2048x1536;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "logo")
@Cascade({ CascadeType.ALL })
@JsonIgnore
private MenuStyleVO menuStyleLogo;
}
如果L使用以下hibernate条件代码从数据库加载QuestionVO类 - 还会加载MenuStyleVO和ApplicationImageVO的所有惰性字段。
在复杂的用例上,这导致此查询变得非常慢
public QuestionVO findMasterAppQuestionById(int id) {
Criteria criteria = currentSession().createCriteria(QuestionVO.class);
criteria.add(Restrictions.eq("id", id));
QuestionVO questionVO = (QuestionVO) criteria.uniqueResult();
return questionVO;
}
我想知道的是 - 是否可以加载QuestionVO类及其急切字段并告诉hibernate忽略其他类中的懒字段以及那些需要的字段?
干杯 达明
答案 0 :(得分:1)
上次我们遇到这样的问题时,我们在父类上使用了一个构造函数,它只使用了确定查询的所需字段。
我完全不记得jpql查询中的构造函数是如何工作的,但它必须是这样的:
select new com.package.class(c.field1, c.field2) from com.package.class c
请记住,具有相同参数的构造函数必须存在于所需的实体上。
优点: - 更好的查询性能; - 可以与其他参数一起复制;
缺点: - 非常有限,你只能在你正在查询的主要实体上使用这个黑客; - 仅包含用于确定查询的构造函数,设计不佳;
另外,你应该看一下JPA的EnttyGraphs。似乎非常有希望,但在我们的项目中没有按照预期工作。
顺便说一句,Hibernate已经多次提出我们的性能问题,希望这个黑客帮助你,祝你好运!编辑:
为什么这种模式会对性能问题有所帮助? 基本上,通过我之前展示的示例,您不是通过Hibernate加载所有内容,只加载主实体的两个字段(field1和field2)。在不使用构造函数的情况下,您无法做到这一点,因为您的查询不会产生所需实体的集合,而是每次迭代(Object [])的两个对象的集合。使用构造函数模式,您将创建所需实体的实例,但只从数据库中选择几个字段,这就是为什么这个模式可以帮助您,您只返回一个只有几个字段的所需实体的集合。