In the previous examples I created and used collections that represented simple value elements or components. However one thing that I wanted to try is deleting from collections. Removing the value from the collection for a session bound
entity should ensure the deletion of the row from the appropriate database table.
For Collection of <elements>
I am using the same example used in the earlier post. Here I simply wrote a function to load the person object and delete an element from a map, set and a list. The code is as below
List Removal
The query executed to fetch elements for the List property in the person entity is
Map Removal
Hibernate executed the below query to load the map instance
I repeated the same for the Component example and got similar results. To ensure correct deletion and readability of logs I implemented the toString(), hashCode() and equals() method in the Component class. Something I should have done in my earlier post itself :(
Removal from Set
The SQL Select query to fetch to set is
Removal from List
The SQL Select query to fetch the list property is
Removal from Map
The select query for map is
There is no need to make any explicit delete calls to achieve the same.
entity should ensure the deletion of the row from the appropriate database table.
For Collection of <elements>
I am using the same example used in the earlier post. Here I simply wrote a function to load the person object and delete an element from a map, set and a list. The code is as below
static void deleteElements() { Session session = sessionFactory.openSession(); Transaction t = session.beginTransaction(); //removing an element from the set Person person = (Person) session.get(Person.class, 1L); person.getKids().remove("Kid ZZZ"); t.commit(); t = session.beginTransaction(); //removing an element from the list person.getDegress().remove(0); t.commit(); t = session.beginTransaction(); //removing an element from the map person.getDegreeScore().remove("Degree 1"); t.commit(); }Based on the logs, I have pulled out lines of interest: Before we proceed to deletion, this is what the Person object looks like before deletion:
13782 [main] DEBUG org.hibernate.pretty.Printer - com.collection.basic.Person{i d=1, degreeScore=[52, 82, 71], degress=[Degree 1, Degree 2, Degree 3], kidsAge=[ 12, 15], name=Raman, hobbies=[Music, Sleeping, Video Games], kids=[Kid YYY, Kid ZZZ]}Set Removal
6906 [main] DEBUG org.hibernate.loader.Loader - loading collection: [com.colle ction.basic.Person.kids#1] 16906 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - about to open PreparedS tatement (open PreparedStatements: 0, globally: 0) 16906 [main] DEBUG org.hibernate.SQL - select kids0_.PERSON_ID as PERSON1_0_, kids0_.KID as KID0_ from PERSON_KIDS kids0_ where kids0_.PERSON_ID=?Hibernate executes a query to fetch the set of kids when I access the kid property of the person entity. The other collections are uninitiated.
17047 [main] DEBUG org.hibernate.pretty.Printer - com.collection.basic.Person{i d=1, degreeScore=<uninitialized>, degress=<uninitialized>, kidsAge=<uninitialize d>, name=Raman, hobbies=<uninitialized>, kids=[Kid YYY]} ... 17047 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersiste r - Deleting rows of collection: [com.collection.basic.Person.kids#1] 17047 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - about to open PreparedS tatement (open PreparedStatements: 0, globally: 0) 17047 [main] DEBUG org.hibernate.SQL - delete from PERSON_KIDS where PERSON_ID=? and KID=?The logs are generated as a part of the deletion. Removal from the set is enough to remove the element from the database table. The logs displays the set, after the element (Kid ZZZ) is removed.
List Removal
The query executed to fetch elements for the List property in the person entity is
284188 [main] DEBUG org.hibernate.SQL -
select
degress0_.PERSON_ID as PERSON1_0_,
degress0_.DEGREE as DEGREE0_,
degress0_.DEGREE_INDEX as DEGREE3_0_
from
PERSON_DEGREES degress0_
where
degress0_.PERSON_ID=?
The logs that indicate the deletion are as below (Degree 1 is missing from the list.):284219 [main] DEBUG org.hibernate.pretty.Printer - com.collection.basic.Person{ id=1, degreeScore=<uninitialized>, degress=[Degree 2, Degree 3], kidsAge=<uninit ialized>, name=Raman, hobbies=<uninitialized>, kids=[Kid YYY]} 284219 [main] DEBUG org.hibernate.SQL - delete from PERSON_DEGREES where PERSON_ID=? and DEGREE_INDEX=?
Map Removal
Hibernate executed the below query to load the map instance
395469 [main] DEBUG org.hibernate.SQL -
select
degreescor0_.PERSON_ID as PERSON1_0_,
degreescor0_.SCORE as SCORE0_,
degreescor0_.DEGREE as DEGREE0_
from
PERSON_DEGREE_SCORE degreescor0_
where
degreescor0_.PERSON_ID=?
The logs indicating the deletion is as follows:395688 [main] DEBUG org.hibernate.pretty.Printer - com.collection.basic.Person{ id=1, degreeScore=[82, 71], degress=[Degree 2, Degree 3], kidsAge=AS can be seen the degreeScore field now has only 2 entries., name=Raman, hobbies= , kids=[Kid YYY]} ... 395688 [main] DEBUG org.hibernate.SQL - delete from PERSON_DEGREE_SCORE where PERSON_ID=? and DEGREE=?
I repeated the same for the Component example and got similar results. To ensure correct deletion and readability of logs I implemented the toString(), hashCode() and equals() method in the Component class. Something I should have done in my earlier post itself :(
@Override public int hashCode() { int hash = this.getName().hashCode(); hash = hash * 17 + this.getBrand().hashCode(); return hash; } @Override public boolean equals(Object obj) { boolean isEqual = false; if (obj instanceof Chocolate) { Chocolate chocolate = (Chocolate) obj; isEqual = chocolate.getName().equals(this.getName()) && chocolate.getBrand().equals(this.getBrand()); } return isEqual; } @Override public String toString() { return "{Chocolate: [Name: " + this.getName() + "], [Brand: " + this.brand + "]}"; }Now an initial snapshot of the ChocolateLover Entity:
3000 [main] DEBUG org.hibernate.pretty.Printer - com.collection.basic.Chocolate
Lover{id=1, name=Robert, chocolateSet=[component[name,brand]{name=Eclairs, brand
=Cadburys}, component[name,brand]{name=Melody, brand=Parle}], chocolateList=[com
ponent[name,brand]{name=Melody, brand=Parle}, component[name,brand]{name=Eclairs
, brand=Cadburys}], chocolateMap=[component[name,brand]{name=Melody, brand=Parle
}, component[name,brand]{name=Eclairs, brand=Cadburys}]}
The above logs indicate that Hibernate's Printer class uses its own display techniques (and does not give a damn about my toString() method :( ) The code for deletion testing is as below:static void deleteElements() { Chocolate chocolateToRemove = new Chocolate(); chocolateToRemove.setName("Eclairs"); chocolateToRemovesetBrand("Cadburys"); Session session = sessionFactory.openSession(); Transaction t = session.beginTransaction(); //removing an element from the set ChocolateLover chocoLover = (ChocolateLover) session.get(ChocolateLover.class, 1); chocoLover.getChocolateSet().remove(chocolateToRemove); t.commit(); t = session.beginTransaction(); //removing an element from the list chocoLover.getChocolateList().remove(chocolateToRemove); t.commit(); t = session.beginTransaction(); //removing an element from the map chocoLover.getChocolateMap().remove(2); t.commit(); }The above code removes the Eclairs chocolates from each of the collection. The logs provide further details about the deletion on removal of the element from each of the collection.
Removal from Set
The SQL Select query to fetch to set is
7703 [main] DEBUG org.hibernate.SQL -
select
chocolates0_.CL_ID as CL1_0_,
chocolates0_.CHOCOLATE_NAME as CHOCOLATE2_0_,
chocolates0_.CHOCOLATE_BRAND as CHOCOLATE3_0_
from
CHOCOLATE_SET chocolates0_
where
chocolates0_.CL_ID=?
The deletion logs indicate the absence of eclairs from the set36828 [main] DEBUG org.hibernate.pretty.Printer - com.collection.basic.Chocolat eLover{id=1, name=Robert, chocolateSet=[component[name,brand]{name=Melody, brand =Parle}], chocolateList=, chocolateMap= } 36828 [main] DEBUG org.hibernate.SQL - delete from CHOCOLATE_SET where CL_ID=? and CHOCOLATE_NAME=? and CHOCOLATE_BRAND=?
Removal from List
The SQL Select query to fetch the list property is
783390 [main] DEBUG org.hibernate.SQL -
select
chocolatel0_.CL_ID as CL1_0_,
chocolatel0_.CHOCOLATE_NAME as CHOCOLATE2_0_,
chocolatel0_.CHOCOLATE_BRAND as CHOCOLATE3_0_,
chocolatel0_.CHOCOLATE_INDEX as CHOCOLATE4_0_
from
CHOCOLATE_LIST chocolatel0_
where
chocolatel0_.CL_ID=?
Similarly the Logs for the deletion is 164625 [main] DEBUG org.hibernate.pretty.Printer - com.collection.basic.Chocola teLover{id=1, name=Robert, chocolateSet=[component[name,brand]{name=Melody, bran d=Parle}], chocolateList=[component[name,brand]{name=Melody, brand=Parle}], chocolateMap=} 83406 [main] DEBUG org.hibernate.SQL - delete from CHOCOLATE_LIST where CL_ID=? and CHOCOLATE_INDEX=?
Removal from Map
The select query for map is
135843 [main] DEBUG org.hibernate.SQL -
select
chocolatem0_.CL_ID as CL1_0_,
chocolatem0_.CHOCOLATE_NAME as CHOCOLATE2_0_,
chocolatem0_.CHOCOLATE_BRAND as CHOCOLATE3_0_,
chocolatem0_.FAVOURITE_RANK as FAVOURITE4_0_
from
CHOCOLATE_MAP chocolatem0_
where
chocolatem0_.CL_ID=?
And the logs for deletion indicate the removal from the map and the subsequent delete query that was fired by Hibernate164625 [main] DEBUG org.hibernate.pretty.Printer - com.collection.basic.Chocola
teLover{id=1, name=Robert, chocolateSet=[component[name,brand]{name=Melody, bran
d=Parle}], chocolateList=[component[name,brand]{name=Melody, brand=Parle}], choc
olateMap=[component[name,brand]{name=Melody, brand=Parle}]}
164625 [main] DEBUG org.hibernate.SQL -
delete
from
CHOCOLATE_MAP
where
CL_ID=?
and FAVOURITE_RANK=?
From the above examples we can conclude, that once the element/component is removed from an associated collection, the corresponding row is deleted from the database.There is no need to make any explicit delete calls to achieve the same.
No comments:
Post a Comment