监听数据库表更新/更改

时间:2013-12-17 13:03:30

标签: mysql sql database hibernate java-ee

我是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,如何实现这种监听器来监听数据库表中的更改/更新?

3 个答案:

答案 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的回答中一样,只是将记录写入持久的媒介,复制它们。您还会遇到陈旧条目的问题:如果您录制新角色,删除和/或更新它并且您的客户回来了怎么办?您是否向他们展示了您的更改日志 - 或者只是最终结果?