0

我使用 EmailAlert bean 作为 DTO 通过 Hibernate 获取数据。所以,我的课程只包含我在 DB 中的字段。但在某些情况下,我需要在 EmailAlert 中添加其他字段来保存中间数据。例如“标题”字段 - 将在 java 端根据用户区域设置、时间等计算。

所以,我有一些变体来解决这个问题。

  1. 向 EmailAlert bean 添加附加属性(例如:标题),但不要将其映射到 DB 表的任何字段。缺点:在这种情况下,我们必须不要在 hashCode() 和 equals() 中使用“caption”属性,因为:

    • 它真的没有问题 - 字段仅包含中间数据
    • 我不确定这不是缓存和休眠本身问题的原因。
      我认为拥有 class 的属性但不要在 equals() 和 hashCode() 方法中使用它是非常难看的。
      将来有人可能会对这种逻辑感到困惑。
  2. 通过添加“caption”属性将 EmailAlert 扩展为 EmailAlertExt。以及将 EmailAlert 作为参数的构造函数。
    但在这种情况下,我不确定水下石头是否会再次将 EmailAlert 作为 EmailAlertExt bean 存储到 DB 中。

  3. 通过添加“caption”属性将 EmailAlert 扩展为 EmailAlertExt2,并引用原始对象。在这种情况下,EmailAlertExt2 的行为与原始 EmailAlert 相同,但我们需要额外的属性。如果我们保存 EmailAlert,我们可以调用 EmailAlertExt2 的 getOriginalValue(),它将返回对原始对象的引用。缺点:编码太多:)

伙计们,这些解决方案中哪个更好?可能有人有其他建议吗?

4

3 回答 3

2

使用 '@Transient' 它不会映射到 db hibernate 会忽略这个字段

于 2012-12-28T16:54:51.777 回答
1

仅仅因为您想将映射字段与非映射字段分开而扩展模型对象并不是一个好主意。一个好的指导方针是问自己一个问题“EmailAlert 和 EmailAlertX 之间有什么区别,我可以清楚地定义我将使用其中一个而不是另一个的情况吗?”。如果你不能清楚地回答这个问题,或者如果你意识到你将总是使用你的子类而不是父类,那肯定表明父类应该是抽象的或者你有太多的类。

在您的特定情况下,将映射和非映射属性都放在同一个类上并标记非映射属性以便您的 ORM 提供程序不会尝试处理它们会更有意义。您可以通过将这些属性注释为@Transient 来做到这一点。

public class EmailAlert implements Serializable {
   @Id
   private Long id;

   @Column(name = "recipient")
   private String recipient;

   @Transient
   private transient String caption;

   // Constructor, Getters/Setters, etc
}

另外,关于您对 hashcode/equals 方法的评论。您没有也不应该在这些方法中包含 Java Bean 的每个属性。仅包括以下属性:

  • 需要唯一标识对象
  • (相当)保证在对象的生命周期内具有相同的值
于 2012-12-28T16:59:12.317 回答
0

听起来您目前需要的 EmailAlert 对象是一个业务对象,因为“中间数据”和“在 java 端计算”位。

也许使用 EmailAlertDto 对象来填充 EmailAlertBusiness 的字段并将额外的标题字段和方法存储在业务对象中。

于 2012-12-28T16:59:02.530 回答