什么用,托管bean(支持bean)或实体bean?

Mr *_*ark 14 entity bean-validation jsf-2 managed-bean

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

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

Arj*_*jms 14

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

对于@Entity bean,获取任意新实例通常没有多大意义.@Entity与持久身份密切相关.因此,这样的实体是Entity Manager从bean容器而不是从bean容器请求的.

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

在一些非常简单的系统中,人们有时确实将服务命名为EL,因此可直接用于EL.但是,最终您经常希望让"支持代码"生成面部消息或处理(表)选择,这些都不应该是纯业务服务的关注点.

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

但是让实体 - 备用bean是罕见的并且反对常见的Java EE模式.

请注意,backing bean可以直接返回实体,因此仍然可以使用bean验证.对于很久以前悄悄爬行的奇怪的"分散/聚集"模式,没有必要(参见本问题的第二个例子).

例如

@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(..., ...);
     }
 }
Run Code Online (Sandbox Code Playgroud)

假设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>
Run Code Online (Sandbox Code Playgroud)

如果有约束,SomeEntity.name它将被验证.

  • @Nimnio scatter/gather将模型的各个属性分散到辅助bean的属性中,然后在action方法中收集其所有值并再次将其存储在原始模型中.因此假设你有模型用户具有属性`name`和`age`,那么支持bean还有两个额外的属性`name`和`age`,THESE绑定到表单.在action方法中有代码如:"user.setAge(this.age); user.setName(this.name);`.如果他们的模型已经说出了20个属性并且它已经在所有地方完成,那么这变得特别麻烦. (2认同)