我是Hibernate的新手。我正在使用Java和Hibernate开发后端服务。
我有一个Student
实体,它与Group
实体有多对多的关系。那是在数据库中,我有一个student
表和一个group
表:
@Entity
@Table(name = "student")
public class Student {
private int student_id; //primary key
@ManyToMany(mappedBy = "students")
private Set<Group> groups = new HashSet<Group>();
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="student_group",
joinColumns={@JoinColumn(name="student_id")},
inverseJoinColumns={@JoinColumn(name="group_id")})
public Set<Group> getGroups() {
return groups;
}
public void setGroups(Set<Group> groups) {
this.groups = groups;
}
//Setter & Getter for student_id
...
}
正如您在上面的hibernate注释中看到的,数据库中有一个连接表student_group
。我想要实现的是,当客户的请求到达我的后端服务(带有学生ID)时,我想知道数据库中的student_group
联接表是否已更新对于该学生,例如是否插入新行(新组)(分配给该学生)或现有行是否已更新值。如果有这样的更新/更改,我会通知客户。
使用hibernate,如何实现这种监听器来监听数据库表中的更改/更新?
答案 0 :(得分:0)
您可以通过编写插入和更新触发器来实现此目的。
可以在表级创建触发器。它们与您使用的ORM框架无关。可以将插入触发器配置为在插入之前触发。可以将更新触发器配置为在更新之前或之后执行。以下链接提供了触发器的简要说明:
http://docs.oracle.com/cd/B12037_01/appdev.101/b10795/adfns_tr.htm
答案 1 :(得分:0)
如果通过hibernat发生数据库操作,您应该能够使用Hibernate event listeners
例如:
public class CreateListner extends DefaultSaveOrUpdateEventListener {
@Override
public void onSaveOrUpdate(SaveOrUpdateEvent event) {
//Do your capturing operation here
super.onSaveOrUpdate(event);
}
}
http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/events.html#objectstate-events
另外,您也可以查找Hibernate Interceptor
Interceptor接口提供从会话到的回调 应用程序,允许应用程序检查和/或操作 保存,更新,删除之前持久对象的属性 或装载。一个可能的用途是跟踪审计信息
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/events.html http://www.mkyong.com/hibernate/hibernate-interceptor-example-audit-log/
答案 2 :(得分:0)
就个人而言,我不建议在这里使用听众。您的问题归结为在student_group
表中添加时间戳。 This question已经有了此代码。原来你的联接表需要是@Embeddable
或两个单独的@OneToMany
关系。
例如,您可以:
@Entity
public class Student {
@Id @GeneratedValue
private Long id;
@OneToMany(mappedBy = "student", cascade = CascadeType.ALL)
private List<StudentGroup> groupRels;
}
public class StudentGroup {
@Id @GeneratedValue
private Long id;
@Version
private DateTime lastChanged;
@ManyToOne
private Student student;
@ManyToOne
private Group group;
}
每次实体更新时,Hibernate都会使用当前时间更新lastChanged
。
如果你有这个,你可以简单地查询时间戳大于客户上次访问时间的StudentGroup
(但是你记录了它)并包含某个学生。如果有这样的事情,请返回完整的Student
记录,否则没有。
我不确定,但即使映射属性的元素发生更改,IIRC Hibernate也会更新@Version
属性,因此您可以将@Version
添加到Student
并保留@ManyToMany
。但我并不是百分之百确定 - 无论如何,单独的映射是安全的选择。
听众的方法就像在Satheesh Cheveri的回答中一样,只是将记录写入持久的媒介,复制它们。您还会遇到陈旧条目的问题:如果您录制新角色,删除和/或更新它并且您的客户回来了怎么办?您是否向他们展示了您的更改日志 - 或者只是最终结果?