我应该如何以及何时从 JSF dataTable 的数据库加载模型
我有一个数据表,如下所示:
<h:dataTable value="#{bean.items}" var="item">
我想用从服务方法获取的数据库中的集合填充它,以便在初始 (GET) 请求期间打开页面时立即显示该集合。我应该什么时候调用服务方法?为什么?
- 在页面加载之前调用它。但如何呢?
- 在页面加载期间调用它。如何?
- 在 getter 方法中调用它。但它被调用了多次。
- 还有别的事吗?
I've a data table as below:
<h:dataTable value="#{bean.items}" var="item">
I'd like to populate it with a collection from the database obtained from a service method so that it is immediately presented when the page is opened during an initial (GET) request. When should I call the service method? And why?
- Call it before page is loaded. But how?
- Call it during page load. How?
- Call it in the getter method. But it is called multiple times.
- Something else?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 bean 的
@PostConstruct
方法中执行此操作。并让
value
引用属性(而不是方法!):或者当您只想迭代而不自动生成 HTML 时:
在
@PostConstruct
中,您具有执行它的优势< em>构建和依赖注入之后。因此,如果您使用 EJB 执行数据库交互任务,@PostConstruct 肯定是正确的位置,因为注入的依赖项在普通构造函数中尚不可用。此外,当使用使用代理的 Bean 管理框架(例如 CDI@Named
)时,构造函数可能会也可能不会按照您期望的方式调用。在检查类、生成代理和/或创建代理期间可能会多次调用它。至少不要在 getter 中执行数据库交互工作,除非它是延迟加载并且您确实无法执行任何其他操作。也就是说,它将在每次迭代期间被调用。在每次迭代期间调用服务方法的效率很低,并且可能最终在呈现和回发期间产生“奇怪”的副作用,例如数据库中的旧值似乎仍然保留在模型中,而不是新提交的值。
如果您依赖 GET 请求参数,请改用
和
。另请参阅 创建 master -实体的详细信息页面、如何链接它们以及选择哪个 bean 范围。如果您想在同一视图(例如 CRUD 表/对话框)上的回发中保留模型(
items
属性),则将 bean 设置为@ViewScoped
,否则将模型设置为@ViewScoped
当在其他地方同时编辑同一模型时,将不会与视图同步。另请参阅 创建 master -详细表和对话框,如何重用相同的对话框来创建和编辑。如果您在模型上使用 JPA 的
@Version
功能,那么您可以捕获OptimisticLockException
来处理它并显示一条消息,例如“数据已被其他人编辑,请刷新/检查所需的更改是否符合预期”。另请参阅 让表示层 (JSF)从服务层(EJB)处理业务异常。另请参阅:
Do it in bean's
@PostConstruct
method.And let the
value
reference the property (not method!):Or when you merely want to iterate without autogenerating HTML:
In the
@PostConstruct
you have the advantage that it's executed after construction and dependency injection. So in case that you're using an EJB to do the DB interaction task, a@PostConstruct
would definitely be the right place as injected dependencies would not be available inside a normal constructor yet. Moreover, when using a bean management framework which uses proxies, such as CDI@Named
, the constructor may or may not be called the way you expect. It may be called multiple times during inspecting the class, generating the proxy, and/or creating the proxy.At least do not perform the DB interaction job in the getter, unless it's lazy loading and you really can't do anything else. Namely, it would be invoked during every iteration round. Calling the service method during every iteration round is plain inefficient and may end up in "weird" side effects during presentation and postbacks, such as old values from DB seemingly still sticking around in the model instead of new submitted values.
If you rely on GET request parameters, then use
<f:viewParam>
and<f:viewAction>
instead. See also Creating master-detail pages for entities, how to link them and which bean scope to choose.If you want to preserve the model (the
items
property) across postbacks on the same view (e.g. CRUD table/dialog), then make the bean@ViewScoped
, else the model won't be in sync with the view when the same model is concurrently edited elsewhere. See also Creating master-detail table and dialog, how to reuse same dialog for create and edit.If you utilize JPA's
@Version
feature on the model, then you can catchOptimisticLockException
to deal with it and show a message like "The data has been edited by someone else, please refresh/review if the desired changes are as intended". See also Letting the presentation layer (JSF) handle business exceptions from service layer (EJB).See also: