【发布时间】:2012-07-09 08:54:28
【问题描述】:
在 S.O. 上有很多帖子。与执行 Hibernate 验证、捕获异常等相关的其他站点。然而,所有这些都让我在下面描述的情况下遇到了一些非常不理想的设计选择。这似乎是一种常见的情况,我不敢相信没有一个干净的解决方案。
- 我想利用 Javax(和 Hibernate)的验证注释,
- 我想更正或丢弃无效对象,
- 我想利用 javax 的 PrePersist 等注释来处理我的对象上的重复或基于时间的操作。
同时使用这三个似乎不起作用。
发生异常时Hibernate won't let you commit a transaction。只要我有一个无效的对象,我就会得到一个违反约束的异常。我无法权威地找到 ConstraintViolationException 是否包含在其中,或者被视为特殊情况[1],但是...
-
如果我捕捉到 ConstraintViolationException 并继续处理下一个对象,我似乎能够继续,但是当我尝试刷新或提交事务时,Hibernate 会抱怨,因为I have objects which have not been assigned an id (by the database)。
- 我曾想过尝试将对象设置为 null 或使用 session.evict(myObject) 来“破坏”Hibernate 对对象的了解。
- 我可以在尝试保存之前[“手动”运行验证](http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#d0e2697),但代价是它被执行了两次——这看起来很愚蠢,但这并不调用@PrePersist 钩子,导致错误的违规行为。
一个人做什么?
具体来说,我有很多 (10,000+) 个对象,其中一小部分总是无效的。
@Entity
public class myPojo implements Serializable {
@Id
@GeneratedValue
private long id;
@NotBlank
private String anotherString;
@NotNull
@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
@NotNull
@Temporal(TemporalType.TIMESTAMP)
private Date updatedAt;
@NotNull
@Temporal(TemporalType.TIMESTAMP)
private Date postedDate;
@PrePersist
protected void onPrePersist() {
this.createdAt = new Date();
this.updatedAt = this.createdAt;
if (this.postedDate == null)
this.postedDate = this.createdAt;
}
}
我想保存这个函数,并捕获任何违反约束的对象:
void saveResource(MyPojo myPojp) {
try {
session.saveOrUpdate(mypojo);
}
catch (final ConstraintViolationException ex) {
System.err.println("Could not save " + myPojo + " because " +
this.getValidationErrors(myPojo));
}
}
其中 getValidationErrors() 返回一个字符串,其中包含通过手动创建和使用验证工厂找到的所有 ConstraintViolation。
我知道的唯一其他可能性是围绕每次保存执行单个事务(这似乎是个坏主意,因为如果确实发生真正的异常,我不希望任何项目持续存在)或者可能编写自定义验证器在调用 prepersist 挂钩的 save 之前手动运行(可维护性噩梦!)。
[1]:我知道这是一个糟糕的参考,但我读了这么多书,我再也找不到了。希望有人能在更多技术细节中澄清哪些错误会导致交易无效还是可以恢复。
【问题讨论】:
-
在什么情况下您希望保存一些对象而不是放弃整个事务?
标签: java mysql hibernate persistence