We know that in dealing with hibernate-many of the problems, we generally in the configuration file Zhong stated below their relations and operations Rules .
For example, when doing Web page, the article will list owners and Bo is the one to many relationship. I use to achieve their cascading hiberbnate relationship profile as follows
Blogger Userinfo.hbm.xml code:
<hibernate-mapping> <!-- Specifies the class to the table mapping --> <class name="test.pojo.Userinfo" table="userinfo"> <!-- Primary key id of the generating mechanism :native Automatically generated according to the database, mysql is the growth mode --> <id name="id" column="id"> <generator></generator> </id> <!-- Set each property Userinfo class to userinfo The corresponding column in the table mappings --> <property name="name" column="name" /> <property name="psw" column="psw"/> <property name="signature" column="signature"/> <property name="sex" column="sex"/> <property name="age" column="age"/> <property name="birthday" column="birthday"/> <property name="qq" column="qq"/> <property name="e_mail" column="e_mail"/> <property name="phone" column="phone"/> <property name="occupation" column="occupation"/> <property name="score" column="score"/> <property name="graduateSchool" column="graduateSchool"/> <property name="country" column="country"/> <property name="province" column="province"/> <property name="head_path" column="head_path"/> <!--save-update --> <!-- Mapping Userinfo object and Article Object relationship to pair more article By way of mapping id The sort order, and delay-load --> <bag name="articles" table="article" order-by="id asc" lazy="false" cascade="all-delete-orphan" > <key column="userid"></key> <one-to-many></one-to-many> </bag> </class> </hibernate-mapping>
In fact, a key is
<bag name="articles" table="article" order-by="id asc" lazy="false" cascade="all-delete-orphan" > <key column="userid"></key> <one-to-many></one-to-many> </bag>
This is a cascade realization of the object and the object relations
Articles Article.hbm.xml code:
<hibernate-mapping> <!-- Specifies the class to the table mapping --> <class name="test.pojo.Article" table="article"> <!-- Primary key id of the generating mechanism :native Automatically generated according to the data, mysql is the growth mode --> <id name="id" column="id"> <generator></generator> </id> <!-- Set each property Article class to article The corresponding column in the table mappings --> <property name="title" column="title"></property> <property name="content" column="content"></property> <property name="publishTime" column="publishTime"></property> <property name="published" column="published"></property> <property name="clickCount" column="clickCount"></property> <property name="type" column="type"></property> <!-- Set the Article object and Userinfo The object of a many-to-one relationship --> <many-to-one name="user" fetch="select" cascade="delete" outer-join="true"> <column name="userid"/> </many-to-one> </class> </hibernate-mapping>
The key section is
<many-to-one name="user" fetch="select" cascade="delete" outer-join="true"> <column name="userid"/> </many-to-one>
This was the test "by", "change", "Charles" is achievable, but delete can not.
Now, I want to delete a blogger code:
Userinfo temuser=userDao.getUserinfoById(4); userDao.deleteUser(temuser);
Will report the following error:
Hibernate: select userinfo0_.id as id0_0_, userinfo0_.name as name0_0_, userinfo0_.psw as psw0_0_, userinfo0_.signature as signature0_0_, userinfo0_.sex as sex0_0_, userinfo0_.age as age0_0_, userinfo0_.birthday as birthday0_0_, userinfo0_.qq as qq0_0_, userinfo0_.e_mail as e9_0_0_, userinfo0_.phone as phone0_0_, userinfo0_.occupation as occupation0_0_, userinfo0_.score as score0_0_, userinfo0_.graduateSchool as graduat13_0_0_, userinfo0_.country as country0_0_, userinfo0_.province as province0_0_, userinfo0_.head_path as head16_0_0_ from userinfo userinfo0_ where userinfo0_.id=? Hibernate: select articles0_.userid as userid0_1_, articles0_.id as id1_, articles0_.id as id1_0_, articles0_.title as title1_0_, articles0_.content as content1_0_, articles0_.publishTime as publishT4_1_0_, articles0_.published as published1_0_, articles0_.clickCount as clickCount1_0_, articles0_.type as type1_0_, articles0_.userid as userid1_0_ from article articles0_ where articles0_.userid=? order by articles0_.id asc Query user ' xiang ' success ! Hibernate: update article set userid=null where userid=? 1953 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: 22001 1953 [main] ERROR org.hibernate.util.JDBCExceptionReporter - Data truncation: Column was set to data type implicit default; NULL supplied for NOT NULL column 'userid' at row 1 1953 [main] ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session org.hibernate.exception.DataException: Could not execute JDBC batch update at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:102) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:262) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:180) at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206) at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:375) at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137) at test.DAO.UserinfoDAO.deleteUser(UserinfoDAO.java:70) at test.test.TestUserinfo.main(TestUserinfo.java:25) Caused by: java.sql.BatchUpdateException: Data truncation: Column was set to data type implicit default; NULL supplied for NOT NULL column 'userid' at row 1 at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1213) at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:912) at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268) ... 9 more
Why is this?
We first look at its implementation of the sql statement, why it should update the article list?
In fact the inverse hibernate with a great relationship, and now look at the inverse:
The following is the interpretation of Baidu Encyclopedia of the inverse
Hibernate in the inverse relationship in the table mapping is often applied
inverse value of two, "true" and "false". inverse = "false" is the default value, if set to true change of state, said object is not synchronized to the database; set to false is the opposite;
inverse role: in hibernate is determined by inverse set is going to protect tables and relationships between tables.
We say that the establishment of improper inverse will lead to poor performance, he actually was inverse set up properly, will have to repeat the SQL statements and even unwanted result JDBC exception of the throw. This is the kind of relationship in the entity must establish areas of concern. In general, inverse = true is recommended, two-way associated with the two sides are set to inverse = false, then both sides will lead to a relationship with repeat update. But if both sides set inverse = true, then the relationship between the two sides did not maintain updated, this is not work, fortunately in the end-to-many: many-to-one by default is the inverse = false, to avoid the generation of this error . However-many would not have the default settings, and so many people at both ends of often-many using inverse = true, Results lead to the fundamental connection table of the data is not recorded, because they have no responsibility to maintain double-points relationship. Therefore, the best two-way set association is one end inverse = true, one end inverse = false. General inverse = false will be placed over one end, then the question was raised as a, many-to-many on both sides are many, inverse in the end go? In fact hibernate many to many relationship is also established separate them into two-to-many relationship in the middle connected to a connection table. Therefore, there is one to many common relationships, can be said: one to many is an essential component of many to many.
Where there is still a difference between when inverse cascade and
cascade is defined in relation to the target object at both ends of the cascade relations; and the definition of the inverse cascade relations and object relations.
inverse only set + one-to-many (or many-to-many) valid for many-to-one, one-to-one invalid. cascade on the relationship between markers are effective.
inverse of the collection object as a whole work, cascade to the collection object in an element of a work, if the set is empty, then the cascade will not lead to association operations.
In binernate also written in the document
Very Important Note: If the <key> column of a <one-to-many> association is declared NOT NULL, Hibernate may cause constraint violations when it creates or updates the association. To prevent this problem, you must use a bidirectional association with the many valued end (the set or bag) marked as inverse = "true".
Therefore to solve the cascade of "additions and deletions to change search" issue, should be "one to many" relationship in the "party" setting inverse = true;
<bag name="articles" table="article" order-by="id asc" lazy="false" cascade="all-delete-orphan" inverse="true"> <key column="userid"></key> <one-to-many></one-to-many> </bag>