In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains "what is the one-to-many relationship of Hibernate mapping". The content of the explanation is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "what is the one-to-many relationship of Hibernate mapping".
In the domain model, the most common relationship between classes is association. In UML, associations have a direction. Take the relationship between customer (Customer) and order (Order) as an example, a customer can place multiple orders, and an order can only belong to one customer.
The association from Order to Customer is many-to-one, which means that each Order object references a Customer object, so a property of type Customer should be defined in the Order class to reference the associated Customer object.
The association from Customer to Order is an one-to-many association, which means that each Customer object references a set of Order objects, so a collection type property should be defined in the Customer class to reference all associated Order objects.
First, establish an one-way relationship between many and one.
As in the example above, we only need to define a customer property in the Order class, but there is no need to define the collection property that holds the Order object in the Customer class.
Order.java
Package mypack; public class Order implements java.io.Serializable {private long id; private String orderNumber; private Customer customer;// defines a Customer attribute public Order () {} public Order (Customer customer) {this.customer = customer;} public Order (String orderNumber, Customer customer) {this.orderNumber = orderNumber; this.customer = customer } / / omitted the construction method of id,orderNumber public Customer getCustomer () {return this.customer;} public void setCustomer (Customer customer) {this.customer = customer;}}
All the properties of the Customer class correspond to the fields in the CUSTOMERS table one-to-one, so you can use the following mapping code directly:
The orderNumber property of the Order class corresponds to the ORDER_NUMBER field in the ORDERS table, and the mapping code is similar to the above, omitted here. Our main concern is the customer attribute in the Order class, because it is of type Customer and corresponds to the foreign key CUSTOMER_ID of the ORDERS table, its real value exists in the CUSTOMERS table, and the ORDERS table stores only a reference to it, so the mapping method of customer cannot be the same as above.
Demonstrate using the method "Bussiness.java:
Package mypack; import org.hibernate.*; import org.hibernate.cfg.Configuration; import java.util.*; public class BusinessService {public static SessionFactory sessionFactory; static {try {/ / initialization Configuration config = new Configuration (); config.configure (); sessionFactory = config.buildSessionFactory ();} catch (RuntimeException e) {e.printStackTrace (); throw e }} / * find the record according to the customer_id of customer specified by the parameter * / public List findOrdersByCustomer (Customer customer) {Session session = sessionFactory.openSession (); Transaction tx = null; try {tx = session.beginTransaction (); List orders=session.createQuery ("from Order as o where o.customer.id=" + customer.getId ()) .list () / / Hibernate execution: select * from ORDERS where CUSTOMER_ID=customer.getId (); tx.commit (); return orders;} catch (RuntimeException e) {if (tx! = null) {tx.rollback ();} throw e;} finally {session.close () }} / * find the record of the specified customer_id according to OID * / public Customer findCustomer (long customer_id) {Session session = sessionFactory.openSession (); Transaction tx = null; try {tx = session.beginTransaction (); Customer customer= (Customer) session.get (Customer.class,new Long (customer_id)); tx.commit (); return customer } catch (RuntimeException e) {if (tx! = null) {tx.rollback ();} throw e;} finally {session.close ();}} / * public void saveCustomerAndOrderWithCascade () {Session session = sessionFactory.openSession (); Transaction tx = null; try {tx = session.beginTransaction () Customer customer=new Customer ("Jack"); / / create a Customer persistent object / / do not save the customer object. If executed, an exception Order order1=new Order ("Jack_Order001", customer); Order order2=new Order ("Jack_Order002", customer); / / create two Order objects session.save (order1); session.save (order2); tx.commit () } catch (RuntimeException e) {if (tx! = null) {tx.rollback ();} e.printStackTrace ();} finally {session.close ();}} * / public void saveCustomerAndOrder () {Session session = sessionFactory.openSession (); Transaction tx = null; try {tx = session.beginTransaction () Customer customer=new Customer ("Tom"); / / create a Customer persistence object session.save (customer); Order order1=new Order ("Tom_Order001", customer); Order order2=new Order ("Tom_Order002", customer); / / create two Order objects session.save (order1); session.save (order2); / / insert ORDERS table tx.commit () twice to the same customerHibernate } catch (RuntimeException e) {if (tx! = null) {tx.rollback ();} throw e;} finally {session.close ();}} public void printOrders (List orders) {for (Iterator it = orders.iterator (); it.hasNext ();) {Order order= (Order) it.next () System.out.println ("OrderNumber of" + order.getCustomer (). GetName (): "+ order.getOrderNumber ());}} public void test () {saveCustomerAndOrder (); / / saveCustomerAndOrderWithCascade (); Customer customer=findCustomer (1); List orders=findOrdersByCustomer (customer); printOrders (orders);} public static void main (String args []) {new BusinessService (). Test () SessionFactory.close ();}}
If the method saveCustomerAndOrderWithCascade () in the above code does not have the sentence session.save (customer)
A PropertyValueException exception is thrown during execution, mainly because:
Before calling the session.save (order1) method, both order1 and customer objects are temporary, and temporary objects are created by new, both of which are not persisted. Assuming that session.save (order1) is successfully executed, order1 will be successfully persisted and become a persistent object, but Hibernate will not automatically persist the customer object associated with order1.
When executing session.save (order1), the CUSTOMER_ID field inserted into the ORDERS table record is null, which violates the database integrity constraint, that is, CUSTOMER_ID is not allowed to be null in the ORDERS table.
The question assumes that the CUSTOMER_ID field in the ORDERS table is allowed to be null:
If executed in this way, two pieces of data can be successfully inserted into the ORDERS table, but when Hibernate automatically cleans up (flush) all persistent objects in the cache, a new exception is thrown
Org.hibernate.TransientObjectException:object references an unsaved transient instance-save the transient instance before flushing: mypack.Customer
The so-called cleanup means that Hibernate updates the database synchronously according to the changes in the properties of persistent objects. During cleanup, Hibernate will find that both order1 and order2 refer to the temporary object customer, while the CUSTOMER_ID field in the ORDERS table is null, which means that the properties of the persisted object in memory are inconsistent with the records in the database. The error is reported because the customer property in order1 refers to a temporary object, Customer.
Thus, when Hibernate persists an object, other objects associated with it are not automatically persisted by default. However, we want the associated Order object to be persisted automatically when Hibernate persists the Customer object, and we can modify the mapping file as follows:
When the cascade property is "save-update", indicating that when an object is saved or updated, the object associated with it is saved or updated in a cascade. As in the example above, when saveCustomerAndOrderWithCascade () is executed, Hibernate persists the order1 with the customer object, and Hibernate executes the
Insert into CUSTOMERS (ID,NAME) values (2, "Jack"); insert into ORDERS (ID,ORDER_NUMBER,CUSTOMER_ID) value (3, "Jack_Order001", 2)
Mapping one-to-many two-way association relationship
By establishing relationships between class classes, you can easily navigate from one object to another or another group of objects associated with it. As in the example above, for a given Order object, if you want to get the Customer object associated with it, you can call directly as follows:
Customer customer=order.getCustomer ()
So for a given Customer object, how do you get all the Order objects associated with it at once? Since the Customer object is not associated with the Order object in the above example, we can also query the database through Hibernate API:
List orders=session.createQuery ("from Order as o where o.customer.id =" + customer.getId ()) .list ()
It is obvious that this will be inefficient, and complex relationships can have an impact on programming. We can have one-to-many two-way associations for Customer and Order resumes.
In the first part, we have established a many-to-one association between the Order class and the Customer class, and now we add an one-to-many association from Customer to the Order class.
Customer.java file:
Package mypack; import java.util.HashSet; import java.util.Set; / / Hibernate requires that when a collection class property is defined in a persistent class, the property must be declared as an interface type. Public class Customer implements java.io.Serializable {private long id; private String name; private Set orders = new HashSet (); / / is initialized as a collection implementation class, which improves the robustness of the program and avoids the application's method of accessing the orders collection with the word null and throwing NullPointerException. Public Customer () {} public Customer (String name, Set orders) {this.name = name; this.orders = orders;} / / omitted id,name 's get and set access methods public Set getOrders () {return this.orders;} public void setOrders (Set orders) {this.orders = orders;}}
Next is the configuration Customer.hbm.xml of the mapping file:
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.