Hibernate collection mappings are often used for both "inverse" and "cascade" properties. For me, hibernate contact is not deep and the language level of all kinds of factors, found that these two properties is difficult to understand, helpless had to this two attribute interpretation work to Google and Baidu, see a lot of cow people's explanation, plus their own in the Eclipse debugging, on the " Inverse "and" cascade "have some insight into these two properties.
Probe into the "inverse" attribute
"Inverse"-literal translation is the meaning of "reversal, make upside down", the written interpretation of "whether the relationship to maintain the power of the other side" (this explanation is really enough pain of the-_-!!, is not understand). The "inverse" property in Hibernate has only two values of "true" and "false". "True" indicates that the power to maintain the relationship is given to the other party, "false" means that the maintenance power is not surrendered (the default value).
For example, there are two tables, customer and orders, their relationship is one-to-many, customer is a party, orders are multiparty.
drop table if exists Customer;drop table if exists orders;create table customer ( ID varchar (255) NOT NULL, Usernam e varchar (255), password varchar (255), Age Integer, register_time datetime, primary key (ID)); create Table orders ( ID varchar (255) NOT NULL, ordernumber varchar (255), balance integer, customer_id varchar (255), primary key (ID));
The two tables correspond to the HBM files, corresponding to the Pojo class:
/*customer table corresponding to the Pojo class */public classes customer{ private String ID; Private String username; private String password; Private Timestamp registertime; private int age; Private set<order> orders = new hashset<order> (); Public Customer () { } /*get and set method*/}/*orders table corresponding Pojo class */public classes order{ private String ID ; Private String ordernumber; private int balance; Private customer customer; Public Order () { }/ * Get and set method*/}
<!--hbm files for the Customer class--
Here are some test code to test the properties of the "inverse" property:
Scenario One: Set "inverse" to true to allow multiparty maintenance relationships
try {tx = Session.begintransaction (); /* Create a Customer object and set its property value */Customer customer = new Customer (); Customer.setusername ("Zhangsan"); Customer.setpassword ("123456"); Customer.setage (22); Customer.setregistertime (New Timestamp () (New Date (). GetTime ())); /* * Create order Object Order1 and set its property value */order Order1 = New Order (); Order1.setordernumber ("a1a2a3"); Order1.setbalance (1000); Order1.setcustomer (customer);//Associate the Customer object to the Order1 object/* * Create order Object Order2 and set its property value */Order Order2 = New Order (); Order2.setordernumber ("D3d2d1"); Order2.setbalance (670); Order2.setcustomer (customer);///The Customer object is associated to the Order2 object Customer.getorders (). Add (order1);//Order1 to As associated to the Customer object custoMer.getorders (). Add (order2);//associates the Order2 object to the Customer object Session.saveorupdate (customer); Tx.commit (); } catch (Exception e) {if (tx! = null) {tx.rollback (); } e.printstacktrace (); } finally {session.close (); }
The data in the database is updated to:
Customer table:
Orders table:
Now Order1.setcustomer (customer); This code is commented out and run the program again:
Customer table:
Orders table:
You can see the significant difference, the first time you save "id" = "402881e534ea7c750134ea7c76bc0001" data, the Orders table has two data inserted, their customer_id are the primary key value of the corresponding record in customer , and the second time you save the data for the record "id" = "402881e534ea81be0134ea81bfea0001", because the original code snippet was previously Order1.setcustomer (customer); The record that order1 represents in the data inserted in the Order table has no customer_id value.
From the above phenomenon can help to understand the "inverse" this property. First, the "inverse" control relationship maintains power, so what is "relationship"? , what is the concrete manifestation of the relationship? In the example above, "relationship" is the relationship between two tables, usually "one-to-many", "one-to-two", "many-to-many" three relationships, and the relationship is embodied in the CUSTOMER_ID column in the Orders table, and "inverse" The attribute is to tell Hibernate which party has the power to manage and maintain this column. The above example sets "inverse" to true so customer_id this column is maintained by a multiparty (order object). This shows that only the order object's operations on the relationship are reflected in the database. (An object-to-relationship operation is an action on an associated property, such as an Order object's "customer" property action on itself, and a customer object to its own orders collection (set<order>) operation)
For example, take the Customer object id= "402881e534ea7c750134ea7c76bc0001" out of the database and get a collection of order objects associated with the Customer object. Deletes the order object that is associated with the customer object.
Customer customer = (customer) session.get (Customer.class, "402881e534ea7c750134ea7c76bc0001"); Order order = (order) Session.get (Order.class, "402881e534ea7c750134ea7c76ce0002"); SYSTEM.OUT.PRINTLN ("Customer Association Order Count:" +customer.getorders (). Size ()); Customer.getorders (). Remove ( order); SYSTEM.OUT.PRINTLN ("Customer Association Order Count:" +customer.getorders (). Size ()); Session.saveorupdate (customer);
Console Output:
Customer Association Order Count:2
Customer Association Order Count:1
You can see that the collection of order objects associated with the customer has actually been deleted, and if the operation is valid, it indicates that the order object has no relation to the customer object, reflecting that the customer_id of the order object should be set to NULL in the database. Now look at the database data:
See, just that operation is a useless operation, will not be reflected in the database. Let's Change the program code:
Customer customer = (customer) session.get (Customer.class, "402881e534ea7c750134ea7c76bc0001"); Order order = (order) Session.get (Order.class, "402881e534ea7c750134ea7c76ce0002"); Order.setcustomer (null); Session.saveorupdate (customer);
This time we use the order object to manipulate the relationship, detach the order object from the Customer object, and if the operation is valid, reflect that the value of the Customer_ID field in the database that should be the order object becomes null, and now look at the database:
As you can see, this operation was successfully reflected in the database.
In case two, the "inverse" property is set to "false", both sides maintain the relationship (because no one is handing over power, "inverse" default value is "false", and "inverse" property can only be set in Set, list, map and several other tags, Tags such as many-to-one cannot set the property value of "inverse", they can only take the value "false")
This will produce the performance problems described in the book (embarrassed, this is also understood for a long time), this can not be understood by any means, I am this (-_-!! ), so I recommend using third-party software to display the binding values of the SQL statements that hibernate outputs (as you can see here). Performance is the result of the problem, when you operate the relationship is no reason to produce some update statements, such as you use the above example to save a customer object, it is associated with 2 order object, it will not only generate 3 INSERT statements (for inserting data), Also generates 2 Update statements (the customer_id of the associated order object is updated to its own primary key value), and you want to be a customer object that contains tens of thousands of of the Order object (Shopaholic), then each time you save it you have to generate more than tens of thousands of update statements. This is a very serious performance problem.
Why does hibernate produce an UPDATE statement? That is hibernate too active, too enthusiastic, too responsible for the performance, it is afraid that you have errors, for example, there are tens of thousands of order objects need to be associated to the customer object, which requires calling Order.setcustomer (customer); Tens of thousands of objects this is not a person can be wrong to complete. So hibernate is afraid you're going to make a mistake. Forget to call this method, so he will update the customer_id field of all associated objects once the order object is saved and ensure correctness, which will result in the above performance problem.
After setting "inverse" to false, you can try setting Order1.setcustomer (NULL), which will still correctly insert the customer's primary key value into the order's customer_id field. Just one more UPDATE statement.
"Cascade" Property
"Cascade"-literal translation is the meaning of "cascade, concatenation," the written interpretation of "This property will enable us to operate the main object, while Hibernate helps us to complete the corresponding operation of the subordinate object (for example, there are two tables of customer and order, the relationship is one-to-many, When only using JDBC to delete a row of records in the Customer table, we also need to manually delete all records associated with it in the order table, using Hibernate's ' cascade ' property, when we delete a customer record, Hibernate will help us to complete the deletion of the corresponding order table records, which facilitates our work) ".
Summarize
When using the "inverse" attribute, you should consider the relationship clearly, or your system will have a large performance problem (but I may not know, now is a general college students have no actual combat experience-_-!!, to continue efforts ~_~), books and some cattle people suggest that the relationship is generally maintained by "multi-party", When encountered "many-to-many" when what to do, in fact, many to how long is two "one-to-many", arbitrarily set a party "inverse" for "true" on it, do not set or neither set (embarrassed, I started is rigid such settings). Instead of using the "Cascade" property, the main object (one side) is generally set to "all", while the parties do not recommend setting the option to include the delete operation, it is recommended to set the multi-party as "Save-update", which is because you delete the side, the parties do not have the meaning of existence, Deleting multiple parties does not mean that a party is meaningless (for example, consumers and orders). Finally, "Cascade" operates on two tables of records or objects at both ends, while "inverse" operates on two table relationships or two object relationships.
Inverse properties and Cascade properties in Hibernate