One-way multi-to-one ing of Hibernate and Its Derivative Problems

Source: Internet
Author: User

One-way multi-to-one ing of Hibernate and Its Derivative Problems

Since data tables can be associated through foreign keys, when Hibernate is used to map objects in a data table with an association relationship, you need to map the object association with the foreign key Association of the data table.

1. Preface

This article is titled one-way, many-to-one. In fact, it paves the way for future ing and HQL operations. It is easy to implement one-way, many-to-one, one-to-many, or two-way, many-to-one, after all, there are too many tools, but when we use them, we seldom consider its mechanism, for example, using the entity class to automatically generate hbm. xml file or hbm is generated by the data table through reverse engineering. xml file, its primary key generation mechanism is not the same. Let's talk a little bit about it.

First, create hibernate. cfg. xml and the session factory class HibernateUtil, and then add two entity classes to be operated and corresponding ing files.

HibernateUtil is as follows:

Package com. zzh. util; import org. hibernate. session; import org. hibernate. sessionFactory; import org. hibernate. boot. registry. standardServiceRegistry; import org. hibernate. boot. registry. standardServiceRegistryBuilder; import org. hibernate. cfg. configuration; public class HibernateUtil {private static SessionFactory sessionFactory; private static Session session; static {// create a Configuration object and read hibernate. cf G. xml file, complete the Initialization Configuration config = new Configuration (). configure (); StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder (). applySettings (config. getProperties (); StandardServiceRegistry ssr = ssrb. build (); sessionFactory = config. buildSessionFactory (ssr);} // get SessionFactory public static SessionFactory getSessionFactory () {return sessionFactory;} // get Session public static Ses Sion getSession () {session = sessionFactory. openSession (); return session;} // close Session public static void closeSession (Session session) {if (session! = Null) {session. close ();}}}View Code

 

Two entity classes: Grade and students

package com.zzh.entity;import java.io.Serializable;import java.util.HashSet;import java.util.Set;public class Grade implements Serializable {    private int gid;    private String gname;    private String gdesc;    public int getGid() {        return gid;    }    public void setGid(int gid) {        this.gid = gid;    }    public String getGname() {        return gname;    }    public void setGname(String gname) {        this.gname = gname;    }    public String getGdesc() {        return gdesc;    }    public void setGdesc(String gdesc) {        this.gdesc = gdesc;    }    public Grade() {        super();    }    public Grade(int gid, String gname, String gdesc) {        super();        this.gid = gid;        this.gname = gname;        this.gdesc = gdesc;    }    public Grade(String gname, String gdesc) {        super();        this.gname = gname;        this.gdesc = gdesc;    }}

 

Package com. zzh. entity; import java. io. serializable; public class Student implements Serializable {private int sid; private String sname; private String sex; // define a reference to private Grade grade in multiple parties; public Grade getGrade () {return grade;} public void setGrade (Grade grade) {this. grade = grade;} public int getSid () {return sid;} public void setSid (int sid) {this. sid = sid;} public String getSname () {return sname;} public void setSname (String sname) {this. sname = sname;} public String getSex () {return sex;} public void setSex (String sex) {this. sex = sex;} public Student () {super ();} public Student (String sname, String sex) {super (); this. sname = sname; this. sex = sex ;}}

 

It can be seen that I declared the Grade attribute using the grade class in the Student class and added getter and setter to reflect the correlation between the entity class Student and Grade, in the following ing table, you only need to configure it on the "multiple" side. Note: The grade attribute added to the Student class is Grade, which is an object attribute of the persistence class Grade and is not a basic type attribute. Therefore, the <property> element cannot be used to map the grade attribute, because it is a many-to-one association, you must use the <strong-to-one> element.

Grade. hbm. xml:

<? Xml version = "1.0"?> <! DOCTYPE hibernate-mapping PUBLIC "-// Hibernate/Hibernate Mapping DTD 3.0 // EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <! -- Generated 2016-8-31 11:19:40 by Hibernate Tools 3.5.0.Final -->  

Student. hbm. xml:

<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!-- Generated 2016-8-31 11:19:40 by Hibernate Tools 3.5.0.Final -->

 

<Role-to-one> the name in the element specifies the attribute name of the join class in the Student class, and column specifies the foreign key associated with the data table. In other words, the multi-to-one association of entity Student to Grade is essentially achieved through the association of the foreign key GRADE in the student of the data table with the grade of the data table, however, Hibernate encapsulates the association between tables through the <transform-to-one> element.

 

2. Write the UserDAO interface that interacts with the database and its implementation class UserDAOImpl, and encapsulate the methods for adding, searching, modifying, and deleting data.

UserDAO:

package com.zzh.dao;public interface UserDAO {    void save(Object obj);    Object findById(int id,Object obj);    void delete(Object obj);    void update(Object obj);}

 

UserDAOImpl:

package com.zzh.dao;import org.hibernate.Session;import org.hibernate.Transaction;import com.zzh.util.*;public class UserDAOImpl implements UserDAO {    @Override    public void save(Object obj) {        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        try {            session.save(obj);            tx.commit();        } catch (Exception e) {            e.printStackTrace();            tx.rollback();        } finally {            HibernateUtil.closeSession(session);        }    }    @Override    public Object findById(int id, Object obj) {        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        try {            obj = session.get(obj.getClass(), id);            tx.commit();        } catch (Exception e) {            e.printStackTrace();        } finally {            HibernateUtil.closeSession(session);        }        return obj;    }    @Override    public void delete(Object obj) {        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        try {            session.delete(obj);            tx.commit();        } catch (Exception e) {            e.printStackTrace();        } finally {            HibernateUtil.closeSession(session);        }    }    @Override    public void update(Object obj) {        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        try {            session.update(obj);            tx.commit();        } catch (Exception e) {            e.printStackTrace();        } finally {            HibernateUtil.closeSession(session);        }    }}

 

Note: My DAO uses Object objects. In many books, multiple DAO objects are created for multiple objects, that is, they are split into StudentDAOImpl and GradeDAOImpl, in this way, the Object is changed to the corresponding Student or Grade.

If you want to rewrite it to a general DAO like me, pay special attention to the findById () method in it. For the DAO written by splitting, this method is very simple, you only need to input the parameter id and then Grade grade = (Grade) session. get (Grade. class, id); and because my method is generic, all object IDs and corresponding objects to be passed in, obj = session. get (obj. getClass (), id), which uses java's reflection knowledge.

1. Call the getClass () method to obtain the Class instance of the object. For example, Students s = new Students (); Class c = s. getClass (); 2. use the static Class method forName () to obtain a Class instance by Class name. For example, Class c = Class. forName ("Students"); 3. application. you can also use the class method to obtain Class instances and encapsulate classes of basic data types. TYPE to obtain the corresponding Class instance of the basic data TYPE; Class c = Students. class; so for my example, obj is used. getClass () is equivalent to Object. you can modify this method by using the class feature.

 

3. Add test case JUnit

Please note that the above hbm. xml file, the primary key generation mechanism is increment

Now the problem is coming again !!! When I use a tool to generate an hbm. xml file through an object class, the primary key generation mechanism is

Assigned indicates that the object identifier is generated by the application. If <generator> node is not specified, this policy is used by default. At this time, the data table has not been created. When I started the test, Hibernate. the problem arises when the database information and related ing information in xml are created. Caused by: com. mysql. jdbc. exceptions. jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '0' for key 'Primary '. The "0 Java class 1 Java software development Class 1" record appears in the Data Table grade, and the "0 Mu goddess female 0" record appears in the data table student, prompting that the primary key already exists, the 0 primary key already exists and cannot be added. Assigned indicates that the program code is responsible for the primary key. Make sure that the primary key data is unique. At this time, I was wondering what would happen if I used identity to generate a policy. identity indicates that the object identifier is generated by the auto-incrementing primary key generation mechanism of the underlying database. Caused by: java. SQL. SQLException: Field 'sid' doesn' t have a default value. It immediately returns that you have not set AUTO_increment in the database. You need to set this value for the two tables.

In this way, you can add them normally.

After I set auto increment, I want to try assigned again, so I changed it to assigned. The problem is that Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; after Baidu, someone explained this exception: the primary key is set to auto-increment, And the ID value is set when we insert the record. I am still looking for solutions. If you have any answers, please let me know.

Then I chose the increment generation policy, which does not need to be set to auto increment in the database. It is very convenient to handle this small example, however, its limitation is that if multiple application instances insert data to the same table, duplicate primary keys will appear. Use it with caution.

4. Summary

This article is messy. After a while, DAO changes and reflection, and finally a bunch of bugs, you still need to accumulate knowledge. If you think this article is a bit useful, please give me a thumbs up. Thank you for watching.

  

 

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.