Search This Blog

Thursday 3 November 2011

Collections of Components

Earlier I created varied collections using the Java String class. In this example I will replace that with a Component class.
public class Chocolate {
    private String name;
    private String brand;        //setter getter methods 
}
The Chocolate class is now used within the Entity object:

public class ChocolateLover {
    private Integer id;
    private String name;

    private List<Chocolate> chocolateList = new ArrayList<Chocolate>();
    private Set<Chocolate> chocolateSet = new HashSet<Chocolate>();
    private Map<Integer, Chocolate> chocolateMap = new HashMap<Integer, Chocolate>();
    private Collection<Chocolate> chocolateBag = new ArrayList<Chocolate>();
        //setter getter methods
}
As can be seen above the ChocolateLover class is full of collections representing chocolates (what else could you expect in a chocolate lover ?? ). The mapping file for the above is :

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.collection.basic">
    <class name="ChocolateLover" table="CHOCOLATE_LOVER">
        <id name="id" type="integer">
            <column name="ID" />
            <generator class="identity" />
        </id>
        <property name="name" type="string">
            <column name="NAME" />
        </property>

        <set name="chocolateSet" table="CHOCOLATE_SET">
            <key column="CL_ID" />
            <composite-element class="Chocolate">
                <property name="name" column="CHOCOLATE_NAME" type="string"
                    not-null="true" />
                <property name="brand" column="CHOCOLATE_BRAND" type="string" />
            </composite-element>
        </set>

        <list name="chocolateList" table="CHOCOLATE_LIST">
            <key column="CL_ID" />
            <list-index column="CHOCOLATE_INDEX" base="1" />
            <composite-element class="Chocolate">
                <property name="name" column="CHOCOLATE_NAME" type="string"
                    not-null="true" />
                <property name="brand" column="CHOCOLATE_BRAND" type="string" />
            </composite-element>
        </list>

        <map name="chocolateMap" table="CHOCOLATE_MAP">
            <key column="CL_ID" /> 
            <map-key column="FAVOURITE_RANK" type="integer" />
            <composite-element class="Chocolate">
                <property name="name" column="CHOCOLATE_NAME" type="string"
                    not-null="true" />
                <property name="brand" column="CHOCOLATE_BRAND" type="string" />
            </composite-element>
        </map>
        <idbag name="chocolateBag" table="CHOCOLATE_BAG"> 
            <collection-id type="long" column="CHOCOLATE_ID"> 
                <generator class="hilo" /> 
            </collection-id> 
            <key column="CL_ID"/>
            <composite-element class="Chocolate"> 
                <property name="name" column="CHOCOLATE_NAME" type="string" not-null="true"/> 
                <property name="brand" column="CHOCOLATE_BRAND" type="string" /> 
            </composite-element> 
       </idbag>
    </class>
</hibernate-mapping>
The mapping file now uses a to represent a component object instead of the element. The hibernate ddl Creation strategy was used as before and the logs indicate the generated sql:

2437 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    create table CHOCOLATE_BAG (
        CL_ID integer not null,
        CHOCOLATE_NAME varchar(255) not null,
        CHOCOLATE_BRAND varchar(255),
        CHOCOLATE_ID bigint not null,
        primary key (CHOCOLATE_ID)
    )1891 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    create table CHOCOLATE_LIST (
        CL_ID integer not null,
        CHOCOLATE_NAME varchar(255),
        CHOCOLATE_BRAND varchar(255),
        CHOCOLATE_INDEX integer not null,
        primary key (CL_ID, CHOCOLATE_INDEX)
    )
1906 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    create table CHOCOLATE_LOVER (
        ID integer not null auto_increment,
        NAME varchar(255),
        primary key (ID)
    )
1906 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    create table CHOCOLATE_MAP (
        CL_ID integer not null,
        CHOCOLATE_NAME varchar(255),
        CHOCOLATE_BRAND varchar(255),
        FAVOURITE_RANK integer not null,
        primary key (CL_ID, FAVOURITE_RANK)
    )
1906 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    create table CHOCOLATE_SET (
        CL_ID integer not null,
        CHOCOLATE_NAME varchar(255),
        CHOCOLATE_BRAND varchar(255)
    )
2500 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table CHOCOLATE_BAG 
        add index FK11C933455BF0FDD8 (CL_ID), 
        add constraint FK11C933455BF0FDD8 
        foreign key (CL_ID) 
        references CHOCOLATE_LOVER (ID)
1922 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table CHOCOLATE_LIST 
        add index FK2761E0E15BF0FDD8 (CL_ID), 
        add constraint FK2761E0E15BF0FDD8 
        foreign key (CL_ID) 
        references CHOCOLATE_LOVER (ID)
1953 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table CHOCOLATE_MAP 
        add index FK11C95C995BF0FDD8 (CL_ID), 
        add constraint FK11C95C995BF0FDD8 
        foreign key (CL_ID) 
        references CHOCOLATE_LOVER (ID)
1969 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
    alter table CHOCOLATE_SET 
        add index FK11C9739F5BF0FDD8 (CL_ID), 
        add constraint FK11C9739F5BF0FDD8 
        foreign key (CL_ID) 
        references CHOCOLATE_LOVER (ID)
The one difference I observed is unlike in the previous example, The table representing the set does not have any primary key, just a foreign key to identify the records. In the previous example the foreign key along with the value field formed the primary key for this table. However on setting both the Component columns as not-null in the hbm the generated sql for the Set changed to include a primary key.

1891 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport  - 
        create table CHOCOLATE_SET (
        CL_ID integer not null,
        CHOCOLATE_NAME varchar(255) not null,
        CHOCOLATE_BRAND varchar(255) not null,
        primary key (CL_ID, CHOCOLATE_NAME, CHOCOLATE_BRAND)
    )
 On executing the code to create an entity

static void createPerson() {
    Chocolate chocolate1 = new Chocolate();
    chocolate1.setName("Melody");
    chocolate1.setBrand("Parle");
        
    Chocolate chocolate2 = new Chocolate();
    chocolate2.setName("Eclairs");
    chocolate2.setBrand("Cadburys");
        
    ChocolateLover chocolateLover = new ChocolateLover();
    Set<Chocolate> chocolateSet = new HashSet<Chocolate>();
    chocolateSet.add(chocolate1);
    chocolateSet.add(chocolate2);
        
    List<Chocolate> chocolateList = new ArrayList<Chocolate>();
    chocolateList.add(chocolate1);
    chocolateList.add(chocolate2);
        
    Map<Integer,Chocolate> chocolateMap = new HashMap<Integer, Chocolate>();
    chocolateMap.put(1, chocolate1);
    chocolateMap.put(2, chocolate2);
    
    Collection<Chocolate> chocolateBag = new ArrayList<Chocolate>();
    chocolateBag.add(chocolate1);
    chocolateBag.add(chocolate2);
             
    chocolateLover.setName("Robert");
    chocolateLover.setChocolateList(chocolateList);
    chocolateLover.setChocolateBag(chocolateBag);
    chocolateLover.setChocolateSet(chocolateSet);
    chocolateLover.setChocolateMap(chocolateMap);
    Session session = sessionFactory.openSession();
    Transaction t = session.beginTransaction();
    session.save(chocolateLover);
    t.commit();
    System.out.println("The Chocolate Lover with name " + chocolateLover.getName() + " was created with id " + chocolateLover.getId());
}
The (cleaned)logs indicate the fired insert statements

3172 [main] DEBUG org.hibernate.SQL  - 
    insert 
    into
        CHOCOLATE_LOVER
        (NAME) 
    values
        (?)
3344 [main] DEBUG org.hibernate.SQL  - 
    insert 
    into
        CHOCOLATE_SET
        (CL_ID, CHOCOLATE_NAME, CHOCOLATE_BRAND) 
    values
        (?, ?, ?)
3359 [main] DEBUG org.hibernate.SQL  - 
    insert 
    into
        CHOCOLATE_SET
        (CL_ID, CHOCOLATE_NAME, CHOCOLATE_BRAND) 
    values
        (?, ?, ?)
3369 [main] DEBUG org.hibernate.SQL  - 
    insert 
    into
        CHOCOLATE_LIST
        (CL_ID, CHOCOLATE_INDEX, CHOCOLATE_NAME, CHOCOLATE_BRAND) 
    values
        (?, ?, ?, ?)
3375 [main] DEBUG org.hibernate.SQL  - 
    insert 
    into
        CHOCOLATE_MAP
        (CL_ID, FAVOURITE_RANK, CHOCOLATE_NAME, CHOCOLATE_BRAND) 
    values
        (?, ?, ?, ?)
3078 [main] DEBUG org.hibernate.SQL  - 
    insert 
    into
        CHOCOLATE_BAG
        (CL_ID, CHOCOLATE_ID, CHOCOLATE_NAME, CHOCOLATE_BRAND) 
    values
        (?, ?, ?, ?)
3390 [main] DEBUG org.hibernate.impl.SessionImpl  - after transaction completion
The Chocolate Lover with name Robert was created with id 1

1 comment: