使用啥,托管 bean(支持 bean)或实体 bean?

Posted

技术标签:

【中文标题】使用啥,托管 bean(支持 bean)或实体 bean?【英文标题】:what to use, managed beans (backing beans) or entity beans?使用什么,托管 bean(支持 bean)或实体 bean? 【发布时间】:2012-01-17 18:56:56 【问题描述】:

我看到很多将 bean 标记为实体 bean (@Entity) 和命名 bean (CDI) 的示例,以避免创建 2 个类(托管 bean 和实体 bean)并利用 Bean Validation 进行验证可以在客户端和服务器上执行。

那么我是否应该使用单个类,是否有任何问题,或者我是否应该让我的托管 bean 或服务层使用托管 bean 中的数据创建实体 bean?

【问题讨论】:

【参考方案1】:

@Named 或 @ManagedBean 注释通常用于让 bean 容器 (CDI/JSF) 在 JSF 中的表达式语言引用时按需创建 bean 的实例。

对于@Entity bean,仅仅获取一个任意的新实例通常没有多大意义。 @Entity 与持久身份的连接非常紧密。因此,此类实体是从 Entity Manager 请求的,而不是从 bean 容器请求的。

典型的模式是有一个(苗条的)支持 bean,该 bean 被命名为调用服务(在 Java EE 中通常是 @Stateless)。然后服务返回实体。

在一些非常琐碎的系统中,人们有时会为服务命名,从而直接对 EL 可用。但是,最终您通常希望让“支持代码”生成人脸消息或处理(表格)选择,这些都是纯业务服务不应该关注的事情。

另一个常见的捷径是让支持 bean 直接包含业务代码(例如,检索实体的实体管理器)。这使得业务代码难以重用,但如果应用程序很简单并且不需要重用,您可能会侥幸成功。

但是让实体作为支持 bean 是罕见的,并且与常见的 Java EE 模式相悖。

请注意,backing bean 可以直接返回实体,所以仍然可以使用 bean-validation。很久以前出现的奇怪的“分散/聚集”模式已经没有必要了(参见this question 中的第二个示例)。

例如

@ViewScoped
@ManagedBean
public class BackingBean 

     private SomeEntity myEntity; // + getter

     @EJB  
     private Service service;

     @PostConstruct
     public void init() 
         myEntity = service.getSomeEntity();
     

     public void save() 
         service.save(myEntity);
         FacesContext.getCurrentInstance().addMessage(..., ...);
     
 

假设 SomeEntity 在 @Entity 注释的 bean 中,bean 验证现在可以在 Facelet 上使用,例如:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
>    
    <h:body>   
        <h:form>      
            <h:inputText value="#backingBean.myEntity.name" />                        
            <h:commandButton value="Save" action="#backingBean.save" />
        </h:form>            
    </h:body>
</html>

如果对 SomeEntity.name 有限制,它将被验证。

【讨论】:

感谢您的帖子,它很有用,但您是否有完整的 JSF 代码示例,我们可以使用并理解编写 JSF 应用程序的适当方式,或者如果您能指出我的一些方向,那就太好了. +1 以获得非常明确的答案,同时也提供了更广泛的问题背景 "请注意,backing bean 可以直接返回实体,所以仍然可以使用 bean-validation。对于奇怪的 'scatter/gather' 模式已经没有必要了前。”我想知道你是否可以详细说明这一点。这种“分散/聚集”模式是什么?这是否相似:我听说有些人主张在视图和模型之间进行更大的分离,因此他们将 Facelets 字段映射到支持 bean 属性(通常是原语),然后他们使用无状态服务来接受属性,执行验证,并填充和持久化实体。 @Nimnio scatter/gather 将模型的各个属性分散到支持 bean 的属性中,然后在 action 方法中收集其所有值并再次将其存储在原始模型中。因此,假设您有具有属性nameage 的模型用户,那么还为支持bean 提供了两个额外的属性nameage,并且这些属性绑定到表单。在 action 方法中,有如下代码:“user.setAge(this.age); user.setName(this.name);`。如果他们的模型有 20 个属性并且到处都是,这会变得特别混乱。 参见***.com/questions/10301363/jpa-entity-as-jsf-bean 了解分散/聚集(反)模式的示例

以上是关于使用啥,托管 bean(支持 bean)或实体 bean?的主要内容,如果未能解决你的问题,请参考以下文章

实体Bean

GlassFish 域中的 JSF 托管 Bean 唯一性

托管 bean 和支持 bean 之间的区别

不是托管类型:类实体。 & 弹簧数据

将 JSF 托管 bean 迁移到 CDI 托管 bean

使用支持 bean 和 jsf 的 Java EE 持久化实体 [重复]