如何避免使用JSF和JPA进行模型代码重复

时间:2010-07-13 08:11:02

标签: jsf jpa code-duplication

我是JSF的新手,我想知道我是否做对了。假设我有一个简单的CMS,可以编写页面。

首先,我定义一个名为Page:

的JPA实体
@Entity
public class Page {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column
  private Long id;

  @Column private String title;

  @Column private String content;

  // getters & setters ...

}

然后我想在视图中创建Page-s。为此,看起来我需要某种页面bean。现在我处理了这样的事情:

@Model
public class PageBean {

  private Page page = new Page();

    public String getTitle() {
      return page.getTitle();
    }

    public void setTitle(String title) {
      page.setTitle(title);
    }

    // rest of properties & getters & setters ...

    public void save() {
      // persist using EntityManager
    }
 }

我的问题是以下问题:鉴于我的JPA实体模型和我想在视图中使用的模型大部分时间完全相同,是否有办法避免必须创建一批getter& ; PageBean中的setter?

我在某处读到你不应该使用与JPA实体和JSF模型bean相同的bean(因为JSF会重复调用可能影响JPA的getter),但我想知道是否有一种更简单的方法可以帮助避免这种代码重复。特别是当你有一个大型模型的应用程序,并且在许多情况下,视图bean中不需要任何特殊的东西,看起来这可能会非常麻烦。

2 个答案:

答案 0 :(得分:4)

  鉴于我的JPA实体模型和我想在视图中使用的模型大部分时间完全相同,是否有办法避免必须创建一批getter& amp; PageBean中的setter?

我没有看到在实体周围使用包装器的意义,并且添加这样的层确实是重复的。只需使用JSF页面中的实体即可。是的,这会在视图和域之间引入某种耦合,但通常,修改数据库通常意味着在视图上添加或删除字段。换句话说,我不会购买“解耦”参数,并且我已经编写了足够的额外层,映射代码,样板代码等,以便在可能的情况下采用简单的方法。

  

我在某处读到你不应该使用与JPA实体和JSF模型bean相同的bean(因为JSF会重复调用可能影响JPA的getter)

如果你能提供引用我会感兴趣但是如果某个地方出现问题,包装类(委托对实体的委托)不会改变任何东西。

以防万一,其他一些资源:

答案 1 :(得分:2)

这不是代码重复。没有算法重复。业务逻辑仍在一个地方。

您的bean正在做的只是将View连接到Domain模型。这很好,它是MVC模式的一部分。

如果您使用JPA实体作为支持bean,那么您将破坏MVC模式。例如,如果有一天而不是显示普通String,则需要向此Date添加String,因为视图需要这样(即接口要求),您要写吗?这个视图逻辑在JPA类中?这没有意义,混合域模型和视图模型。

另一方面,为什么视图必须知道域的实现方式?如果域值格式发生变化怎么办? (例如,出于性能原因,您在de Database中保存时间戳字符串而不是日期类)。你需要做的只是重写支持bean中的方法,它需要时间戳并使其适应日期,所以一切都会像以前一样工作。只是JPA课程之外的一个变化。如果你在JPA类中使用它,你最终只会在一个类中维护逻辑(接口逻辑和域逻辑)。

如果您想开发新视图(例如移动版),该怎么办?你要为JPA课程添加更多代码吗?最好保持JPA不变,并为移动版本创建另一个Bean(扩展两个视图的公共bean)。

如果在这之后,你仍然想不写getter和setter,你可以做

#{myBean.page.title}

你需要的只是支持bean内的getPage()