提交JSF页面时记录了意外的JPA SELECT语句 [英] Unexpected JPA SELECT statements logged when JSF page submitted

查看:97
本文介绍了提交JSF页面时记录了意外的JPA SELECT语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有捆绑JSF的Glassfish Server 4.1.我已经在"persistence.xml"中启用了JPA FINE记录.

I'm using Glassfish Server 4.1 with bundled JSF. I've enabled JPA FINE logging in "persistence.xml".

我有此Facelets页面:

I have this Facelets page:

<p:dataTable var="customer" value="#{customerService.customers}">
</p:dataTable>
<h:form>
    <h:commandButton value="Test"/>
</h:form>

(请注意,这实际上就是全部:我没有将操作与按钮相关联,也没有向表中添加列,并且如果这样做,我将要描述的行为不会改变.还记得默认的render行为是@none.)

(Note that that's really all there is: I haven't associated an action with the button, or added columns to the table, and if I do, the behaviour I'm about to describe doesn't change. Also recall that default render behaviour is @none.)

此无状态EJB(带有@Named,以便页面可以直接引用它):

And this Stateless EJB (with @Named so that the page can refer to it directly):

@Stateless
@Named
public class CustomerService {

    @PersistenceContext
    private EntityManager em;

    public List<Customer> getCustomers() {
        return em.createNamedQuery("Customer.findAll", Customer.class).getResultList();
    }
    ...

当我加载页面时,日志中会显示以下消息:

When I load the page, the following message appears in the log:

Fine:   SELECT ID, CUSTOMERNAME, EMAIL, PAID, QUANTITY, TYPE FROM CUSTOMER

到目前为止,一切都很好.但是,当我单击按钮时,它会出现在日志中:

So far so good. When I click the button though, this appears in the logs:

Fine:   SELECT ID, CUSTOMERNAME, EMAIL, PAID, QUANTITY, TYPE FROM CUSTOMER
Fine:   SELECT ID, CUSTOMERNAME, EMAIL, PAID, QUANTITY, TYPE FROM CUSTOMER
... Same message appears five more times ...

Customers表为空.

The Customers table is empty.

任何人都可以复制或解释这种行为吗?一个用于页面加载的SELECT很有意义,但是七个用于表单提交的SELECT却令人困惑.

Can anyone reproduce or explain this behaviour? One SELECT for page load makes sense, but seven SELECTS for form submit is confusing.

更新

如果我将EJB移到ViewScoped JSF支持bean中并更新Facelets页面以使用它,则行为不会改变:

The behaviour is unchanged if I move the EJB into a ViewScoped JSF backing-bean and update the Facelets page to use it:

@ManagedBean // javax.faces.bean.
@ViewScoped
public class BackingBean {
    @EJB
    private CustomerService cs;
    public List<Customer> getCustomers() {
        return cs.getCustomers();
    } 
}

推荐答案

正如Tiny在对我的问题的评论中解释的那样,发生了额外的日志记录,因为我将业务逻辑放置在Facelets页面所使用的getter方法内.通常不赞成将业务逻辑放入Facelets页面使用的访问器(getter setter)方法中,因为这些方法由JSF框架使用,您几乎无法控制它们的时间和频率被称为.

As Tiny explained in a comment on my question, the extra logging is occurring because I placed business logic inside the getter method used by the Facelets page. It is usually frowned upon to put business logic in the accessors (getter and setter) methods used by Facelets pages, as these methods are used by the JSF framework and you have little control over when and how often they are called.

在这种情况下,可以通过在JSF范围内的backing-bean的@PostConstruct方法中初始化客户来解决"该问题:

In this case the issue can be "fixed" by initializing customers in the @PostConstruct method of a JSF view-scoped backing-bean:

@PostConstruct
public void init() {
    customers = customerService.getCustomers();
}
public List<Customer> getCustomers() {
    return customers;
}

这是一个比较常规的设置,但是我试图在没有JSF支持bean的情况下解决问题.

This is a more conventional set-up, but I was trying to get by without a JSF backing-bean.

如果有人可以解释为什么为什么 JSF框架调用方法次,这似乎是任意的,那么我肯定会将该答案标记为正确,但是与此同时,我对此感到满意.

If someone can explain why the JSF framework is calling the method seven times, which seems arbitrary, I would definitely mark that answer correct, but in the meantime I am satisfied with this.

更新

有关确切呼叫次数(七个)的解释可能与此答案类似,

The explanation for the exact number of calls, seven, is probably similar to this answer, Why is the getter called so many times by the rendered attribute?:

getter调用全部由rendered="#{selector.profilePage == 'some'}"在渲染响应阶段完成.评估false时 第一次在UIComponent#encodeAll()中,然后没有更多呼叫 将会完成.当它评估true时,它将被重新评估 按以下顺序再 6 次...

The getter calls are all done by rendered="#{selector.profilePage == 'some'}" during the render response phase. When it evaluates false the first time, in UIComponent#encodeAll(), then no more calls will be done. When it evaluates true, then it will be re-evaluated six more times in the following sequence...

这篇关于提交JSF页面时记录了意外的JPA SELECT语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆