Hibernate tree-like mapping

Source: Internet
Author: User

Referring to tree-like mapping, many people will certainly have a headache, because looking at the "tree" These two words will certainly think of the data structure to deal with, and data structure is the most important undergraduate stage and the most difficult to learn a professional course. To tell you the truth, I didn't learn the data structure, and it took a little time to finally complete the tree-like mapping of hibernate.

First I defined a company organization class (ORG), an organization can have more than one sub-organization, but each organization has only one parent organization, that is, a legend of the relationship between the two, but the relationship is bidirectional. When it comes to bidirectional relationships, the first thing we do is to have two-way correlations on both sides of the two-way relationship, and in order to prevent redundancy, we have to set the Mappedby in one of the parties, and then explain in the procedure below.

Now that you have determined that the organization class (ORG) is a two-way relationship, how do you define this class? First of all, from the perspective of database table design, each organization may have more than one child organization, and each sub-organization corresponding to only a parent organization, which is a typical one-to-many relationship, an organization has its own ID and organization name (name), these two can already describe the organization, But how do you describe the relationships between organizations? That is, in the table we also have to define the field to withdraw the present relationship. Because it is a one-to-many relationship, a pair of multi-mapping relationship has a rule is very important, that is, it must be in the "many" this side of the "one" of this side of the foreign key , here is in the subordinate organizations set up the foreign key of the organization, so that through this foreign key we can find the organization of the parent Some students may be puzzled: why do you want to set the "one" in the "many" of this side of the foreign key? Instead of the opposite? Take a look at the following example to see why this is set up.

Note: The following are the error design methods in the database table:

GroupId

GroupName

Userid

1

Group_1

1

1

Group_1

2

Userid

UserName

1

Moluo

2

Xingzhe

A group can have multiple users (user), which is a typical one-to-many relationship, if the group (that is, in the "one" of this side) set the user ("many" of this side) of the foreign key, then the table in the red font part of the information is not generated redundant? This results in only two records of redundancy and can be accepted. But what if the group table has a lot of fields and there are many records? The redundancy created by this design is exaggerated, so it must beThis side of " many" sets the foreign key for this side of "one".

Explain how the table in the database is designed, and then how to define the class of the program org.

First Org This class is an organization, from an object-oriented perspective, it has both superior and subordinate organizations, of course, the ID and name of the two attributes are necessary. What's more important is that its superior and subordinate organizations are actually an organization, so I define the following Org class:

Package Com.hibernate.model;import Java.util.hashset;import Java.util.set;import javax.persistence.CascadeType; Import Javax.persistence.entity;import Javax.persistence.fetchtype;import Javax.persistence.generatedvalue;import Javax.persistence.id;import Javax.persistence.joincolumn;import Javax.persistence.manytoone;import Javax.persistence.onetomany;import javax.persistence.Table; @Entity @table (name= "_organization") public class Org { private int id;private String name;private set<org> children = new hashset<org> ();p rivate Org parent; @Id @gene ratedvaluepublic int getId () {return ID;} public void setId (int id) {this.id = ID;} Public String GetName () {return name;} public void SetName (String name) {this.name = name;} @OneToMany (mappedby= "parent", Cascade=cascadetype.all,fetch=fetchtype.eager) public set<org> GetChildren () { return children;} public void Setchildren (set<org> children) {This.children = children;} @ManyToOne @joincolumn (name= "parent_id") public Org getParent () {RETUrn parent; public void SetParent (Org parent) {this.parent = parent;}}
To explain briefly, first the ID self-increment does not explain, explainsMappedby, Mappedby is used to define the relationship between classes and classes, if the class is a one-way relationship with the class, then it is not defined, if it is a bidirectional relationship, then you must define the Mappedby,mappedby to indicate that the foreign key has been set in the "opposite party", and there is no need to set it. If Mappedby is not set, it is likely to produce inconsistencies in the data. In addition, the value of Mappedby should be set to "many" side of the corresponding class "one" side of the variable name, in fact, it should be set to "one" square variable name corresponding to the GetXXX method that xxx, because in rare cases getxxx () and corresponding variable name inconsistent ( This is, of course, a very non-advocating approach).

Let's explain again. Cascade, which defines a cascade relationship between a class and a class, the defined cascading relationship is considered by the container to take the same action as the current class object and the class object associated with it, and the cascading relationship is recursive . The Cascade property values are: all: The same operation for all cases, save, update, delete,PERSIST: This means that the same action is taken when saving, the merge is the official term for JPA, In fact, just like Sava (). Remove: This represents a cascade delete, which is actually the same as the Delete () method;Refresh: Cascade refresh.

Then explain fetch: Fetch is a read operation, it has two properties,LAZY: Indicates that only the current object is read, the associated object is not read;EAGER: When the current object is read, the associated object is read, and This cascade relationship is recursive .

@OneToMany: Indicates that the object (entity) corresponding to the GetXXX () method represented by the current class object (entity) is a one-to-many relationship.

@ManyToOne: Indicates that the object (entity) of this class object (entity) corresponding to the GetXXX () method represented by xxx corresponds to a many-to-one relationship.

@JoinColumn: Used to annotate the name of a field in a table.

Finally, let's look at JUnit Test case:

Package Com.hibernate.model;import Org.hibernate.session;import Org.hibernate.sessionfactory;import Org.hibernate.cfg.annotationconfiguration;import Org.hibernate.tool.hbm2ddl.schemaexport;import Org.junit.afterclass;import Org.junit.beforeclass;import Org.junit.test;public class TreeTest {public static Sessionfactory SF = null, @BeforeClasspublic static void Beforeclass () {try{sf = new annotationconfiguration (). Configure ( ). Buildsessionfactory ();} catch (Exception e) {e.printstacktrace ();} finally{}} @Testpublic void Testsave () {Org o = new org (); O.setname ("head Office"); org O1 = new org (); O1.setname ("Branch 1"); Org O2 = n ew org (); O2.setname ("Branch 2"); org o11 = new org (); O11.setname ("Division 1 under branch 1"), org o12 = new Org (), O12.setname ("Department 2 under branch 1"); O RG O21 = new Org (), O21.setname (department 1 Under branch 2), O.getchildren (). Add (O1); O.getchildren (). Add (O2); O1.getchildren (). Add ( O11); O1.getchildren (). Add (o12); O12.getchildren (). Add (O21); O1.setparent (o); O2.setparent (o); o11.setparent (O1); o 12.setParent (O1); O21.setparent (O2); Session SessIon = Sf.getcurrentsession (); Session.begintransaction (); Session.save (o); Session.gettransaction (). commit (); @Testpublic void TestLoad () {testsave (); Session session = Sf.getcurrentsession (); session.begintransaction (); org o = (org) session.load (org.class, 1);p rint (o,0 ); Session.gettransaction (). commit ();} private void print (Org o,int level) {String prestr = ' "; for (int i=0; i<level; i++) {Prestr + = "_";} System.out.println (Prestr + o.getname ()); for (Org Child:o.getchildren ()) {print (child,level+1);}} @Testpublic void Testschemaexport () {New Schemaexport (new Annotationconfiguration (). Configure ()). Create (False, True) ;} @AfterClasspublic static void Afterclass () {sf.close ();}}
It defines a print () method, in which the level is used to render the printed result in a tree-like structure.

Printing results:

Headquarters _ Branch 2__ branch 2 under the Department 1_ Branch 1__ Branch 1 under the Department 2__ Branch 1 under the Department 1


PostScript: Write this article spend more time than I write this program to spend more time, I hope that if you want to reprint the audience respect the performance of the work of the Moro, note the original link and do not delete my QR code, thank you!

Welcome to follow the public number (Xingzhemoluo), common communication programming experience, scan the following QR code can be;





Hibernate tree-like mapping

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.