我有一个数据表如下:
<h:dataTable value="#{bean.items}" var="item">
我想用从服务方法获取的数据库中的集合填充它,以便在初始 (GET) 请求期间打开页面时立即显示该集合。我应该什么时候调用服务方法?为什么?
用bean的
@PostConstruct
方法来做。
@Named
@RequestScoped
public class Bean {
private List<Item> items;
@Inject
private ItemService itemService;
@PostConstruct
public void init() {
items = itemService.list();
}
public List<Item> getItems() {
return items;
}
}
并让
value
引用属性(而不是方法!)。
<h:dataTable value="#{bean.items}" var="item">
在
@PostConstruct
中,你有一个优势,它是在构建和依赖注入之后执行的。因此,如果您使用 EJB 来执行数据库交互任务,那么 @PostConstruct
肯定是正确的位置,因为注入的依赖项在普通构造函数中尚不可用。此外,当使用使用代理的 bean 管理框架(例如 CDI
@Named
)时,构造函数可能会或可能不会按照您期望的方式调用。在检查类、生成代理和/或创建代理期间可能会多次调用它。至少不要
在getter中执行数据库交互工作,除非它是延迟加载并且你真的不能做任何其他事情。也就是说,它将在每次迭代期间被调用。在每次迭代期间调用服务方法效率很低,并且可能会在呈现和回发期间产生“奇怪”的副作用,例如数据库中的旧值似乎仍然保留在模型中,而不是新提交的值。 如果您依赖 GET 请求参数,则使用
<f:viewParam>
和
<f:viewAction>
代替。另请参阅为实体创建主从页面、如何链接它们以及选择哪个 bean 范围。 如果您想在同一视图(例如 CRUD 表/对话框)上的回发中保留模型(
items
属性),则使 bean
@ViewScoped
,否则模型将不会与视图同步同一模型在其他地方同时编辑。另请参阅创建主从表和对话框,如何重用同一对话框进行创建和编辑。 如果您在模型上使用 JPA 的
@Version
功能,那么您可以捕获
OptimisticLockException
来处理它并显示一条消息,例如“数据已被其他人编辑,请刷新/检查所需的更改是否符合预期” ”。另请参阅让表示层 (JSF) 处理来自服务层 (EJB) 的业务异常。 另请参阅: