Hibernate Interceptor (Interceptor) and Event Listener (Listener)

Source: Internet
Author: User

interceptors (Intercept): As with the Struts2 interceptor mechanism, it is an operation that passes through a layer of interceptors, each of which triggers the event of the appropriate interceptor for preprocessing or aftercare.

  Listener (Listener): In fact, the function is similar to the interceptor, but its implementation principle is different, it is to register one or more listeners for each event, once the event occurs, the event source notifies all listeners listening to the event, and then the listener handles the notification (Observer mode).

Interception device

Hibernate provides us with an interface to implement the Interceptor Org.hibernate.Interceptor, which provides a number of interception events. It is not usually necessary to implement this interface, because it is not possible for us to implement our own interceptors for every event. So hibernate provides us with an empty implementation class org.hibernate.EmptyIntercept for the Org.hibernate.Interceptor interface, usually we just inherit the empty implementation class and override the event method that we need.

The Interceptor works simple:

Once the interceptor is set up, the corresponding operation passes through a layer of appropriate interceptors, allowing the interceptor to perform pre-processing or aftercare.

Examples of interceptor use:

To create an interceptor:

public class Autoupdatetimeinterceptor extends emptyinterceptor{private static        Final long serialversionuid = -8597658125309889388l; /* * Entity-pojo Object * Id-pojo The primary key of the object * State-pojo the collection of each property of the object (except the ID) * Propertynames-pojo object of each property name group Set (except ID) * The set of hibernate types that correspond to each property type of the Types-pojo object (except the ID) */@Override public boolean OnSave (object Enti Ty, Serializable ID, object[] state, string[] propertynames, type[] types) {if (Entity Instanceo F people) {for (int index=0;index<propertynames.length;index++) {/* found named "C Heckintime "Properties */if (" Checkintime ". Equals (Propertynames[index])) {/* use intercept                    The People object's "Checkintime" property is assigned the value */state[index] = new Timestamp (new Date (). GetTime ());                return true;    }}} return false; }}

Scene class

public class client{public    static void Main (string[] args)    {/        * Add interceptors to session */Session        session = Hibernateutil.getsessionfactory (). Opensession (New Autoupdatetimeinterceptor ());        Transaction tx = NULL;        Try        {            tx = Session.begintransaction ();                        People people = new people ();            People.setname ("Zhangsan");                        Session.save (people);                        Tx.commit ();        }        catch (Exception e)        {            if (tx!=null)            {                tx.rollback ();            }                        E.printstacktrace ();        }        Finally        {            session.close ();}}    }

  

The scene class does not display a property value that sets the "checkintime" of the People object, launches the scene class code, and now looks at the database information:

You can see that the Checkin_time property is still assigned, indicating that the assignment is what the interceptor helped us do. When using interceptors, you need to pay attention to the return value of the interceptor, I have always thought that the return value of the interceptor will control whether an operation can continue, through the experiment found that even if the return false operation will continue to execute, but return false, all the interceptor settings are invalid, will not be reflected in the database.

return false:

public class Autoupdatetimeinterceptor extends emptyinterceptor{private static        Final long serialversionuid = -8597658125309889388l; /* * Entity-pojo Object * Id-pojo The primary key of the object * State-pojo the collection of each property of the object (except the ID) * Propertynames-pojo object of each property name group Set (except ID) * The set of hibernate types that correspond to each property type of the Types-pojo object (except the ID) */@Override public boolean OnSave (object Enti Ty, Serializable ID, object[] state, string[] propertynames, type[] types) {if (Entity Instanceo F people) {for (int index=0;index<propertynames.length;index++) {/* found named "C Heckintime "Properties */if (" Checkintime ". Equals (Propertynames[index])) {/* use intercept                  The People object's "Checkintime" property is assigned the value */state[index] = new Timestamp (new Date (). GetTime ());//                return true;    }}} return false; }}

  

To view the inserted data:

You can see that the data is still stored in the database, but the operation of the interceptor is not reflected in the database, and the operation of the interceptor is not valid.
But what's strange is the SQL statement from the console output:

Hibernate:     insert     into        people        (name, checkin_time, id)     values        (?,?,?) Hibernate:     update        people     set        name=?,        checkin_time=?     where        id=?

One more UPDATE statement, I used P6spy to show the binding values for these two SQL statements:

1327304507491|0|0|statement|insert into people (name, checkin_time, id) VALUES (?,?,?) | Insert into people (name, checkin_time, id) VALUES (' Zhangsan ', ' 2012-01-23 15:41:47.45 ', ' 402881e53509837f0135098380370001 ') 1327304507491|0|0|statement|update people set name=?, Checkin_time=? where id=?| Update people set name= ' Zhangsan ', checkin_time= ' where id= ' 402881e53509837f0135098380370001 '

  

As you can see, the action of the interceptor is directly reflected in the database, but if the return value is False, hibernate produces an update SQL statement that cancels the operation result of the interceptor.

Finally, hibernate interceptors are set up in two ways, one using sessionfactory.opensession (Interceptor Interceptor), which only works for the session and is called a local interceptor. The other is set using the Setinterceptor (Interceptor Interceptor) method of the configuration, which is valid for each session and is called a global interceptor.

Event Listener

Basically, each method of the session interface has a corresponding event. such as Loadevent,flushevent, and so on (consult the DTD for the XML configuration file, and the Org.hibernate.event package for a list of all defined events). When a method is called, Hibernate Session generates a corresponding event and activates all configured event listeners. The process of the system preset listener implementation is the method to be listened to do (the method being listened to is only the activation listener, "actual" work is done by the listener). However, you are free to choose to implement a self-customized listener (for example, implement and register the Loadeventlistener interface for processing loadevent) to handle all requests for the load () method that invokes the session.

When defining your own event listeners, there is no need to implement the Xxxlistener interface, and Hibernate has provided a default implementation for each event listener interface to facilitate our definition of event listeners. The default implementations that hibernate provides to us can be found under the Org.hibernate.event.def package, and we just need to inherit these default implementations and add our own custom functionality to it.

The Simple event Listener:

When a method is called, Hibernate Session generates a corresponding event and activates all configured event listeners.

Event listeners use:

To create an event listener:

public class Saveorupdatelistener extends defaultsaveorupdateeventlistener{    private static final long Serialversionuid = 7496518453770213930L;    /* Listen for Save or update event */    @Override public    void Onsaveorupdate (Saveorupdateevent event)    {        people people = NULL;                if (Event.getobject () instanceof people)        {            people = (people) Event.getobject ();        }                People.setcheckintime (New Timestamp () (New Date (). GetTime ()));                System.out.println ("invoke!");                /* Be sure to invoke the functionality provided by the parent class, or it will be the same as the inherited interface */        super.onsaveorupdate (event);}    }

  

Configure the event listener to hibernate through the Hibernate.cfg.xml configuration file:

The first method of configuration:

<event type= "Save-update" >    <listener class= "Com.suxiaolei.hibernate.listener.SaveOrUpdateListener"/ ></event>

The second configuration method:

<listener class= "Com.suxiaolei.hibernate.listener.SaveOrUpdateListener" type= "Save-update"/>

  

Both configurations produce the same effect. Just one with "events" as the main, one to "listener" mainly. The type is the kind that specifies the listening event, class specifies the listener's implementation class, and an event can have multiple listeners. The type has many values, and the following table lists the values for all the type:

Each option in the list above corresponds to a specific event.

Scene class:

public class client{public    static void Main (string[] args)    {        Session session = Hibernateutil.getsessionfactory (). Opensession ();        Transaction tx = NULL;        Try        {            tx = Session.begintransaction ();                        People people = new people ();            People.setname ("Lisi");                        Session.saveorupdate (people);                        Tx.commit ();        }        catch (Exception e)        {            if (tx!=null)            {                tx.rollback ();            }                        E.printstacktrace ();        }        Finally        {            session.close ();}}    }

  

The People object still does not have the Checkintime property set, and after running the program, view the database:

As you can see, the Checkin_time field is still assigned, indicating that the event listener we configured is in effect.

Using event listeners I find it necessary to pay attention to the order of the parent behavior, for example:

public void Onsaveorupdate (Saveorupdateevent event) {        people people = NULL;                if (Event.getobject () instanceof people)        {            people = (people) Event.getobject ();        }                People.setcheckintime (New Timestamp () (New Date (). GetTime ()));                System.out.println ("invoke!");                /* Be sure to invoke the functionality provided by the parent class, or it will be the same as the inherited interface */        super.onsaveorupdate (event);}

  

public void Onsaveorupdate (Saveorupdateevent event) {/        * Be sure to invoke the functionality provided by the parent class, or it will be the same as the inherited interface *        /super.onsaveorupdate ( event);                people people = NULL;                if (Event.getobject () instanceof people)        {            people = (people) Event.getobject ();        }                People.setcheckintime (New Timestamp () (New Date (). GetTime ()));                System.out.println ("invoke!");}

For example, the above sequence, although the final result is consistent, but the second order will produce more than one UPDATE statement, there may be performance problems, so you need to pay more attention when using the event listener.

Hibernate Interceptor (Interceptor) and Event Listener (Listener)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.