我很遗憾地提出这样一个基本问题,但我在其他问题上找不到明确答案:
我有一个班级Foo
public class Foo {
private Integer id;
private String name;
private Bar bar;
// getters and setters
}
另一个班级Bar
public class Bar {
private Integer id;
private String name;
private Set<Foo> foos;
// getters and setters
}
我有ManagedBean
,其ManagedProperty
像这样:
public class FooBean {
@ManagedProperty(value = "{param.barId}"
private Integer barId;
private Bar bar;
private Foo foo;
public FooBean() {
}
@PostConstruct
public void initialize() {
SessionFactory factory = new Configuration().configure().buildSessionFactory();
if barId != null) {
foo = new Foo();
Session session = factory.openSession();
try {
session.beginTransaction();
bar = (Bar) session.load(Bar.class, barId);
foo.setBar(bar);
session.getTransaction().commit();
} catch (Exception ex) {
Transaction tx = session.getTransaction();
if (tx.isActive()) {
tx.rollback();
}
} finally {
session.close();
}
}
}
}
在我的脸上,我试着以这种方式显示数据:
<h:outputText value="#{fooBean.foo.bar.name}" />
哪个不起作用!但如果我将bar.getName()
添加到我的初始化方法(加载栏后),它可以正常工作!
为什么?什么是最佳实践替代方案?
答案 0 :(得分:3)
添加
lazy="false"
表示hibernate mapping xml中的name属性。
答案 1 :(得分:3)
问题是您正在使用
session.load(...)
此方法假定实体存在。因此,它不必查询要检查的数据库,只需返回稍后将加载实体的代理。如果您调用Bar
对象的Getter方法,您将初始化代理,并且您可以在以后进行其他调用而无需数据库访问。
如果您使用
session.get(...)
这不应该发生,因为Hibernate将立即从数据库中获取实体以检查它是否存在并且不返回代理。
答案 2 :(得分:1)
你可以这样做:
第一个选项是global,第二个选项获取该查询的foo.bar。