Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 对变量的设置作出反应_Java_Hibernate_Javabeans - Fatal编程技术网

Java 对变量的设置作出反应

Java 对变量的设置作出反应,java,hibernate,javabeans,Java,Hibernate,Javabeans,我有一个有六个属性和更改日期的类 @Entity @Table(name = "product") public class Product { private Long id; private String title; // if changed, update lastChanged private String subtitle; private Text summary; // if changed, update lastChanged pri

我有一个有六个属性和更改日期的类

@Entity
@Table(name = "product")
public class Product {

   private Long id;

   private String title; // if changed, update lastChanged

   private String subtitle;

   private Text summary; // if changed, update lastChanged

   private Text description; // if changed, update lastChanged

   private Text otherText;

   private List<Text> reviews; // if changed, update lastChanged

   private Date lastChanged;

   // Getters and setters

}
(这显然是我们实际领域模型的一个大规模简化版本,但它说明了基本问题)

要求是:如果“标题”、“摘要”、“说明”或“评论”更改,请将“lastChanged”设置为当前日期。
背景:这些字段与外部API相关。我的客户想知道,自日期X以来,哪些产品对API相关字段进行了更改

我已经尝试通过实现Hibernate拦截器和Hibernate事件侦听器来满足需求。他们都没有像我希望的那样工作。例如,当我更改“summary”时,Hibernate只告诉我:表“text”中的字段“content”已更改

这些信息不是很有用,因为我仍然不知道“摘要”、“说明”或“其他文本”是否已更改。因此,我不知道是否需要更新“lastChanged”

我的其他想法:

  • 获取已更改文本对象的id,并尝试通过SQL查找与其连接的产品。这可能会起作用,但这是一个相当丑陋的解决方案,而且它会变得非常复杂,与我们的领域模型

  • 在变量设置器中实现更新逻辑。这有两个问题:Hibernate在从数据库加载对象时调用setter(当然,这不应该导致更新时间戳),它不能解决上述问题。如果调用了“内容”的setter,那么会发生什么?我不知道,产品的哪个属性已经改变了


这个问题有什么优雅的解决方案吗?

以一种通用的方式解决更改通知问题不是一件小事,特别是当您需要一种不会盲目发送通知的有状态机制时——例如,来自基础结构某些部分的更改不会触发通知

问题的细节也可能使问题变得简单或复杂。例如,同一
文本
对象能否被
产品
对象的多个字段引用?同样,它是否可以在不同的
产品
对象之间共享?如果其中任何一项都是可能的,那么当共享对象发生更改时,您必须确定正确的行动方案-例如,您是否通知所有相关方

构建通知基础架构的基本设计模式之一是。您可以使用此方法让所有
Product
对象观察它们引用的所有
文本
对象中的更改

如果这种方法对于您的目的来说太复杂或太慢,您可能需要重新思考您的体系结构。例如,使
Text
类不可变有意义吗?或者,如果每个
Text
对象仅由单个其他对象引用,是否可以在
Text
中添加一个额外字段,以指向其父对象以及合适的构造函数

至于避免虚假通知,有两种可能的解决方案:

  • 限制对setter的访问以保留它们供任何持久性/序列化机制使用,并为系统的其余部分使用不同的方法集。例如,你可以这样做:

    公共类文本{ 长私形; ... 私有setPrivateId(长x){ privateId=x; }

    }

  • 让Hibernate直接填充字段,而不经过setter——我相信有很多注释,但请记住,这种方法可能会使未来的重构更加困难


您想知道实体的变更属性吗?我不太明白这个问题。您想知道,如果我需要更改实际值(旧值是什么,新值是什么)?那很好,但没必要。
@Entity
@Table(name = "text")
public class Text {

   private Long id;

   private String content;

   private int typeCode;

   // Getters and setters

}
public setId(long x) {
   setPrivateId(x);

   this.triggerChangeNotifiers();
}
...