Search This Blog

Friday 21 October 2011

Hibernate Collections - The whole variety -2

In the last post we saw a java class that included the different collections supported in Hibernate and the mapping file. If we were to start the server with the hibernate set to DDL creation then the logs are as below:
Exception in thread "main" org.hibernate.InvalidMappingException: Could not parse mapping document 
from resource com/collection/basic/Person.hbm.xml
    at org.hibernate.cfg.Configuration.addResource(Configuration.java:569)
    at org.hibernate.cfg.Configuration.parseMappingElement(Configuration.java:1587)
    at org.hibernate.cfg.Configuration.parseSessionFactory(Configuration.java:1555)
    at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1534)
    at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1508)
    at org.hibernate.cfg.Configuration.configure(Configuration.java:1428)
    at org.hibernate.cfg.Configuration.configure(Configuration.java:1414)
    at test.collection.basic.TestPerson.main(TestPerson.java:28)
Caused by: org.hibernate.InvalidMappingException: Could not parse mapping docume
nt from invalid mapping
    at org.hibernate.cfg.Configuration.addInputStream(Configuration.java:502)
    at org.hibernate.cfg.Configuration.addResource(Configuration.java:566)
    ... 7 more
Caused by: org.xml.sax.SAXParseException: The content of element type "idbag" mu
st match "(meta*,subselect?,cache?,synchronize*,comment?,collection-id,key,(elem
ent|many-to-many|composite-element|many-to-any),loader?,sql-insert?,sql-update?,
sql-delete?,sql-delete-all?,filter*)".
Unfortunately I haven't been able to identify the invalid elements in the document. So I decided to remove the mapping for <idbag> and continue with the example:
Update: Fortunately I have finally resolved this issue. - first Joby pointed out that I had missed the table attribute(which I updated in my previous post).
Also the order of the child elements inside <idbag> matters. I changed my idbag definition to the below:
<idbag name="chocolates" table="PERSON_CHOCOLATES">
        
        <collection-id type="long" column="PERSON_CHOCOLATE_ID">
            <generator class="hilo"/>
        </collection-id>
        <key column="PERSON_ID"/>
        <element type="string" column="CHOCOLATE" not-null="true" />
    </idbag>
The identifier class was changed to hilo as the collection-id property was not accesible in the Java object. Also the <collection-id> element was placed above the <key> element.
Now the code works fine.

The logs now read as below:
28  [main] DEBUG org.hibernate.cfg.CollectionSecondPass  - Second pass for coll
ection: com.collection.basic.Person.kids
828  [main] DEBUG org.hibernate.cfg.CollectionSecondPass  - Mapped collection ke
y: PERSON_ID, element: KID
828  [main] DEBUG org.hibernate.cfg.CollectionSecondPass  - Second pass for coll
ection: com.collection.basic.Person.degress
[Second Pass over remaining collections]
...
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  - Static SQL for collection: com.collection.basic.Person.degress
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row insert: insert into PERSON_DEGREES (PERSON_ID, DEGREE_INDEX, DEGREE) va
lues (?, ?, ?)
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row update: update PERSON_DEGREES set DEGREE=? where PERSON_ID=? and DEGREE
_INDEX=?
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row delete: delete from PERSON_DEGREES where PERSON_ID=? and DEGREE_INDEX=?
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  One-shot delete: delete from PERSON_DEGREES where PERSON_ID=? 
 
2375 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  - Static SQL for collection: com.collection.basic.Person.chocolates
2375 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row insert: insert into PERSON_CHOCOLATES (PERSON_ID, PERSON_CHOCOLATE_ID, 
CHOCOLATE) values (?, ?, ?)
2375 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row update: update PERSON_CHOCOLATES set CHOCOLATE=? where PERSON_CHOCOLATE
_ID=?
2375 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row delete: delete from PERSON_CHOCOLATES where PERSON_CHOCOLATE_ID=?
2375 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  One-shot delete: delete from PERSON_CHOCOLATES where PERSON_ID=? 
 
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  - Static SQL for collection: com.collection.basic.Person.hobbies
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row insert: insert into PERSON_HOBBIES (PERSON_ID, HOBBY) values (?, ?)
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row update: update PERSON_HOBBIES set HOBBY=? where PERSON_ID=? and HOBBY=?
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row delete: delete from PERSON_HOBBIES where PERSON_ID=? and HOBBY=?
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  One-shot delete: delete from PERSON_HOBBIES where PERSON_ID=?

2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  - Static SQL for collection: com.collection.basic.Person.degreeScore
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row insert: insert into PERSON_DEGREE_SCORE (PERSON_ID, DEGREE, SCORE) valu
es (?, ?, ?)
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row update: update PERSON_DEGREE_SCORE set SCORE=? where PERSON_ID=? and DE
GREE=?
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row delete: delete from PERSON_DEGREE_SCORE where PERSON_ID=? and DEGREE=?
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  One-shot delete: delete from PERSON_DEGREE_SCORE where PERSON_ID=?

2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  - Static SQL for collection: com.collection.basic.Person.kids
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row insert: insert into PERSON_KIDS (PERSON_ID, KID) values (?, ?)
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row update: update PERSON_KIDS set KID=? where PERSON_ID=? and KID=?
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row delete: delete from PERSON_KIDS where PERSON_ID=? and KID=?
2625 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  One-shot delete: delete from PERSON_KIDS where PERSON_ID=?

2640 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  - Static SQL for collection: com.collection.basic.Person.kidsAge
2640 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row insert: insert into PERSON_KID_AGE (PERSON_ID, KID, AGE) values (?, ?, 
?)
2640 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row update: update PERSON_KID_AGE set AGE=? where PERSON_ID=? and KID=?
2640 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  Row delete: delete from PERSON_KID_AGE where PERSON_ID=? and KID=?
2640 [main] DEBUG org.hibernate.persister.collection.AbstractCollectionPersister
  -  One-shot delete: delete from PERSON_KID_AGE where PERSON_ID=?
... [Select queries for each of the Collection tables] 
2500 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table PERSON_CHOCOLATES 
        drop 
        foreign key FK4C5720E181E2B5D
2734 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table PERSON_DEGREES 
        drop 
        foreign key FK3EB5081D81E2B5D
2843 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table PERSON_DEGREE_SCORE 
        drop 
        foreign key FK9BD7EFE981E2B5D
2875 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table PERSON_HOBBIES 
        drop 
        foreign key FK2310BEE681E2B5D
2922 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table PERSON_KIDS 
        drop 
        foreign key FK68B4A91781E2B5D
2968 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table PERSON_KID_AGE 
        drop 
        foreign key FKB7AF9CDC81E2B5D
3062 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    drop table if exists PERSON
2735 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    drop table if exists PERSON_CHOCOLATES
3109 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    drop table if exists PERSON_DEGREES
3109 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    drop table if exists PERSON_DEGREE_SCORE
3109 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    drop table if exists PERSON_HOBBIES
3125 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    drop table if exists PERSON_KIDS
3125 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    drop table if exists PERSON_KID_AGE
3140 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    create table PERSON (
        ID bigint not null auto_increment,
        NAME varchar(255),
        primary key (ID)
    )
3156 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    create table PERSON_DEGREES (
        PERSON_ID bigint not null,
        DEGREE varchar(255) not null,
        DEGREE_INDEX integer not null,
        primary key (PERSON_ID, DEGREE_INDEX)
    )
2797 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    create table PERSON_CHOCOLATES (
        PERSON_ID bigint not null,
        CHOCOLATE varchar(255) not null,
        PERSON_CHOCOLATE_ID bigint not null,
        primary key (PERSON_CHOCOLATE_ID)
    )
3172 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    create table PERSON_DEGREE_SCORE (
        PERSON_ID bigint not null,
        SCORE integer not null,
        DEGREE varchar(255) not null,
        primary key (PERSON_ID, DEGREE)
    )
3187 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    create table PERSON_HOBBIES (
        PERSON_ID bigint not null,
        HOBBY varchar(255) not null,
        primary key (PERSON_ID, HOBBY)
    )
3203 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    create table PERSON_KIDS (
        PERSON_ID bigint not null,
        KID varchar(255) not null,
        primary key (PERSON_ID, KID)
    )
3218 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    create table PERSON_KID_AGE (
        PERSON_ID bigint not null,
        AGE integer not null,
        KID varchar(255) not null,
        primary key (PERSON_ID, KID)
    )
3218 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table PERSON_DEGREES 
        add index FK3EB5081D81E2B5D (PERSON_ID), 
        add constraint FK3EB5081D81E2B5D 
        foreign key (PERSON_ID) 
        references PERSON (ID)
2844 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table PERSON_CHOCOLATES 
        add index FK4C5720E181E2B5D (PERSON_ID), 
        add constraint FK4C5720E181E2B5D 
        foreign key (PERSON_ID) 
        references PERSON (ID)
3234 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table PERSON_DEGREE_SCORE 
        add index FK9BD7EFE981E2B5D (PERSON_ID), 
        add constraint FK9BD7EFE981E2B5D 
        foreign key (PERSON_ID) 
        references PERSON (ID)
3250 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table PERSON_HOBBIES 
        add index FK2310BEE681E2B5D (PERSON_ID), 
        add constraint FK2310BEE681E2B5D 
        foreign key (PERSON_ID) 
        references PERSON (ID)
3281 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table PERSON_KIDS 
        add index FK68B4A91781E2B5D (PERSON_ID), 
        add constraint FK68B4A91781E2B5D 
        foreign key (PERSON_ID) 
        references PERSON (ID)
3297 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table PERSON_KID_AGE 
        add index FKB7AF9CDC81E2B5D (PERSON_ID), 
        add constraint FKB7AF9CDC81E2B5D 
        foreign key (PERSON_ID) 
        references PERSON (ID)
3312 [main] INFO  org.hibernate.tool.hbm2ddl.SchemaExport  - schema export compl
ete
As can be seen from the logs, the different mapped collections were read by Hibernate at start up and CRUD queries were generated. The CRUD queries were of the form:
  1. Insert into table
  2. Update record in table
  3. Delete selected record
  4. Cascade Delete for a Person. 
The schema created is as follows:
Database Schema
The yellow key symbol next to the column names indicate the Primary Key for each table. I tried to save a Person Instance. I now executed code to create a Person instance.
static void createPerson() {
        Person person = new Person();
        Set<String> kids = new HashSet<String>();
        kids.add("Kid ZZZ");
        kids.add("Kid YYY");
        List<String> degrees = new ArrayList<String>();
        degrees.add("Degree 1");
        degrees.add("Degree 2");
        degrees.add("Degree 3");
        Map<String,Integer> degreeScore = new HashMap<String, Integer>();
        degreeScore.put("Degree 1", 52);
        degreeScore.put("Degree 2", 82);
        degreeScore.put("Degree 3", 71);
        //This will be ignored by Hibernate as it is not mapped
        Collection<String> chocolates = new ArrayList<String>();
        chocolates.add("Nutties");
        chocolates.add("Coffee Bite");
        chocolates.add("Nutties");
        SortedSet<String> hobbies = new TreeSet<String>();
        hobbies.add("Video Games");
        hobbies.add("Music");
        hobbies.add("Sleeping");// Sort will be applied here
        SortedMap<String, Integer> kidsAge = new TreeMap<String, Integer>();
        kidsAge.put("Kid YYY", 12);
        kidsAge.put("Kid ZZZ", 15);    //The kids will be saved and retrieved in ascending
        //even if they are inserted in wrong sequence
        
        person.setChocolates(chocolates);
        person.setDegreeScore(degreeScore);
        person.setDegress(degrees);
        person.setHobbies(hobbies);
        person.setKids(kids);
        person.setKidsAge(kidsAge);
        person.setName("Raman");
        
        Session session = sessionFactory.openSession();
        Transaction t = session.beginTransaction();
        session.save(person);
        t.commit();        
    }
The data inserted is 

The above data indicates that our customized sort comparator applied for the PERSON_KID_AGE table has also not worked. I haven't been able to fix this issue yet. But the rest of the data has been saved as per expectations.

3 comments:

  1. Robin...gr8 post...the idbag elements in the previous post doesn't has table attribute...this could be the reason for the failure of mapping with idbag...

    Joby

    ReplyDelete
  2. Thanks Joby,
    Ya good catch.. I must have missed out the table attribute.
    But I added it and still my xml is indicated as invalid. :(

    ReplyDelete
  3. Got the idbag issue fixed finally :)

    ReplyDelete