【发布时间】:2013-03-24 21:42:14
【问题描述】:
我正在使用 Spring + JSF2 + Hibernate 来构建 Web 应用程序。两个相关的类如下所示:
@Entity
@Table(name="people")
@Named
public class Person implements Serializable {
private int id;
private String forename;
@Inject private PhoneNumber mobile_phone;
/* Other properties */
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="mobile_phone_number_id", nullable = true)
public PhoneNumber getMobilePhone() {
return mobile_phone;
}
/* Other getters and setters */
}
@Entity
@Table(name="phone_numbers")
@Named
public class PhoneNumber {
private Integer id;
private String code;
private String number;
/* Other stuff */
}
依赖注入由 Spring (@Named, @Inject) 处理。数据库持久性通过 Hibernate 注释(@OneToOne、@JoinColumn)进行配置。 JSF 表单元素使用 EL 绑定到这些类。
我的问题是如果所有字段都留空(用户不提交任何值),如何告诉休眠不保存自动绑定的电话号码?换句话说,我希望保存 Person 对象,但不希望 phone_numbers 表中出现空字符串的记录。
如果有人知道,还有两个额外的问题。
- Spring 何时绑定 PhoneNumber - 在创建 Person 时或来自 JSF 的 PhoneNumber 请求时?
- [已解决] 我的表单中有字段没有在 JSF 中用
required属性标记。显然,如果这些字段为空,则不应触发验证。问题是,当我配置 Hibernate 验证器时,即使留空,现在也会验证这些非必填字段。有没有办法跳过对 JSF 中未标记为required的空字段的验证?我尝试在hibernateProperties的SessionFactorybean 中设置<prop key="javax.persistence.validation.mode">CALLBACK</prop>,但这没有帮助。
【问题讨论】:
-
您坚持使用三重奏重聚的不良做法示例。 1. 你绝对不想混淆模型类和支持 bean 类。 2. 您肯定希望将非持久性字段标记为
@Transient。最后,如果您遵循基于应用程序层分离的标准方法,您最终会得到一个正在运行的程序。 -
感谢您的评论!现在这是我对你的陈述的回答。 1. 我有一个 JSF 支持 bean,其中 Person 作为属性被注入。我认为重写支持 bean 中的所有 getter 和 setter 太复杂了。如果我弄错了,请纠正我。 2.
@Transient注解我知道,但事实并非如此,是吗? -
您不需要注入模型(实体)对象。它通常充当数据的 占位符、DTO 或分离实体。它的预加载是在
@PostConstruct方法中完成的。如果要持久化一个新实体,则实例化一个新对象并从视图中填充。这样您就可以通过#{bean.entity.field}在视图中引用它。当然,不需要重复代码。 -
关于
@Transient的用法并非如此,但您应该删除所有@Inject/@Named注释并让它成为一个普通的JPA 实体。一开始我以为你想注入一些不涉及实体本身的东西,所以我建议使用@Transient。 -
感谢您的回复!老实说,我什至没有理会应用架构之类的东西,只是做了一个基础项目,包括 dao、服务、视图和模型层,然后开始编写代码。但现在感谢您的评论,@skuntsel,我决定做一些研究并更仔细地计划。对于那些感兴趣的人,JPA 上有一个很好的资源,它是 Hibernate 实现:blog.xebia.com/category/jpa/implementation-patterns。
标签: spring hibernate validation jsf-2 integration