alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Hibernate example source code file (readonly.xml)

This example Hibernate source code file (readonly.xml) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Hibernate tags/keywords

contract, contract, entities, for, hibernate, hibernate, hql, if, if, java, java, the, to, when

The Hibernate readonly.xml source code

<?xml version='1.0' encoding="UTF-8"?>
<!--
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
  ~ indicated by the @author tags or express copyright attribution
  ~ statements applied by the authors.  All third-party contributions are
  ~ distributed under license by Red Hat Middleware LLC.
  ~
  ~ This copyrighted material is made available to anyone wishing to use, modify,
  ~ copy, or redistribute it subject to the terms and conditions of the GNU
  ~ Lesser General Public License, as published by the Free Software Foundation.
  ~
  ~ This program is distributed in the hope that it will be useful,
  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
  ~ for more details.
  ~
  ~ You should have received a copy of the GNU Lesser General Public License
  ~ along with this distribution; if not, write to:
  ~ Free Software Foundation, Inc.
  ~ 51 Franklin Street, Fifth Floor
  ~ Boston, MA  02110-1301  USA
  -->

<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "../HIBERNATE_-_Relational_Persistence_for_Idiomatic_Java.ent">
%BOOK_ENTITIES;

]>

<chapter id="readonly">
    <title>Read-only entities

    <important>
        <para>
            Hibernate's treatment of <emphasis>read-only entities may 
            differ from what you may have encountered elsewhere. Incorrect usage 
            may cause unexpected results.
        </para>
    </important>

    <para>
        When an entity is read-only:

        <itemizedlist>
            <listitem>
                <para> 
                    Hibernate does not dirty-check the entity's simple 
                    properties or single-ended associations;
                </para>
            </listitem>
            <listitem>
                <para> 
                    Hibernate will not update simple properties or updatable
                    single-ended associations; 
                </para>
            </listitem>
            <listitem>
                <para> 
                    Hibernate will not update the version of the read-only 
                    entity if only simple properties or single-ended 
                    updatable associations are changed;
                </para>
            </listitem>
        </itemizedlist>
    </para>

    <para>
        In some ways, Hibernate treats read-only entities the same as entities that are 
        not read-only:
 
        <itemizedlist>
            <listitem>
                <para> 
                    Hibernate cascades operations to associations as
                    defined in the entity mapping.
                </para>
            </listitem>
            <listitem>
                <para> 
                    Hibernate updates the version if the entity has a 
                    collection with changes that dirties the entity;
                </para>
            </listitem>
            <listitem>
                <para> 
                    A read-only entity can be deleted.
                </para>
            </listitem>
        </itemizedlist>
    </para>

    <para>
        Even if an entity is not read-only, its collection association can 
        be affected if it contains a read-only entity.
    </para>

    <para>
        For details about the affect of read-only entities on different
        property and association types, see 
        <xref linkend="readonly-proptypes"/>.
    </para>

    <para>     
        For details about how to make entities read-only, see 
        <xref linkend="readonly-api"/>
    </para>

    <para>
        Hibernate does some optimizing for read-only entities:
    </para>
        <itemizedlist>
            <listitem>
                <para>
                    It saves execution time by not dirty-checking simple properties or 
                    single-ended associations.
                 </para>
            </listitem>
            <listitem>
                <para>
                    It saves memory by deleting database snapshots.
                </para>   
            </listitem>
        </itemizedlist>

    <section id="readonly-api">
        <title>Making persistent entities read-only

        <para>
            Only persistent entities can be made read-only. Transient and
            detached entities must be put in persistent state before they
            can be made read-only.
        </para>

        <para>
            Hibernate provides the following ways to make persistent entities read-only:
        </para>
    
        <itemizedlist>
            <listitem>
                <para>
                    you can map an entity class as <emphasis>immutable;
                    when an entity of an immutable class is made persistent,
                    Hibernate automatically makes it read-only.
                    see <xref linkend="readonly-api-immutable"/> for details 
                </para>
            </listitem>
            <listitem>
                <para>
                    you can change a default so that entities loaded
                    into the session by Hibernate are automatically 
                    made read-only; see <xref linkend="readonly-api-loaddefault"/> for details
                </para>
            </listitem>
            <listitem>
                <para>
                    you can make an HQL query or criteria read-only so
                    that entities loaded when the query or criteria executes,
                    scrolls, or iterates, are automatically 
                    made read-only; see <xref linkend="readonly-api-querycriteria"/> for details
                </para>
            </listitem>
            <listitem>
                <para>
                    you can make a persistent entity that is already in the
                    in the session read-only; see 
                    <xref linkend="readonly-api-entity"/> for details
                </para>
            </listitem>
        </itemizedlist>

        <section id="readonly-api-immutable">
            <title>Entities of immutable classes

            <para>
                When an entity instance of an immutable class is made 
                persistent, Hibernate automatically makes it read-only. 
            </para>
            <para>
                An entity of an immutable class can created
                and deleted the same as an entity of a mutable class.
            </para>

            <para>
                Hibernate treats a persistent entity of an immutable 
                class the same way as a read-only persistent entity
                of a mutable class. The only exception is that 
                Hibernate will not allow an entity of an immutable
                class to be changed so it is not read-only.
            </para>

        </section>

        <section id="readonly-api-loaddefault">
            <title>Loading persistent entities as read-only
 
            <note>
                <para>
                    Entities of immutable classes are automatically loaded
                    as read-only.
                </para>
            </note>
 
            <para>
                To change the default behavior so Hibernate loads entity 
                instances of mutable classes into the session and automatically 
                makes them read-only, call:
            </para>
            <programlisting role="Java">Session.setDefaultReadOnly( true );

            <para>
                To change the default back so entities loaded by Hibernate are not
                made read-only, call:
            </para>
                <programlisting role="Java">Session.setDefaultReadOnly( false );

            <para>
                You can determine the current setting by calling:
            </para>
            <programlisting role="Java">Session.isDefaultReadOnly();

            <para> 
                If Session.isDefaultReadOnly() returns true, entities loaded by 
                the following are automatically made read-only:
            </para>
            <itemizedlist>
                <listitem>
                    <para>
                        Session.load()
                    </para>
                </listitem>
                <listitem>
                    <para>
                        Session.get()
                    </para>
                </listitem>
                <listitem>
                    <para>
                        Session.merge()
                    </para>   
                </listitem>
                <listitem>
                    <para>
                        executing, scrolling, or iterating HQL queries and 
                        criteria; to override this setting for a particular
                        HQL query or criteria see 
                        <xref linkend="readonly-api-querycriteria"/> 
                    </para>   
                </listitem>
            </itemizedlist>

            <para>
                Changing this default has no effect on:
            </para>
            <itemizedlist>
                <listitem>
                    <para>
                        persistent entities already in the session when the 
                        default was changed
                    </para>
                </listitem>
                <listitem>
                    <para>
                        persistent entities that are refreshed via
                        Session.refresh(); a refreshed persistent 
                        entity will only be read-only if it was 
                        read-only before refreshing
                    </para>
                </listitem>
                <listitem>
                    <para>
                        persistent entities added by the application via 
                        Session.persist(), Session.save(), and Session.update()
                        Session.saveOrUpdate()
                    </para>   
                </listitem>
            </itemizedlist>

        </section>

        <section id="readonly-api-querycriteria">
            <title>Loading read-only entities from an HQL query/criteria 

            <note>
                <para>
                    Entities of immutable classes are automatically loaded
                    as read-only.
                </para>
            </note>

           <para>
                If Session.isDefaultReadOnly() returns false (the default) 
                when an HQL query or criteria executes, then entities 
                and proxies of mutable classes loaded by the query will 
                not be read-only.
            </para>

            <para>
                You can override this behavior so that entities and proxies loaded 
                by an HQL query or criteria are automatically made read-only. 
            </para>

            <para>
                For an HQL query, call:
            </para>
            <programlisting role="Java">Query.setReadOnly( true );

            <para>
                <literal>Query.setReadOnly( true ) must be called before
                <literal>Query.list(), Query.uniqueResult(),
                <literal>Query.scroll(), or Query.iterate()
            </para>

            <para>
                For an HQL criteria, call:
            </para>
            <programlisting role="Java">Criteria.setReadOnly( true );

            <para>
                <literal>Criteria.setReadOnly( true ) must be called before
                <literal>Criteria.list(), Criteria.uniqueResult(),
                or <literal>Criteria.scroll()
            </para>

            <para>
                Entities and proxies that exist in the session before being returned
                by an HQL query or criteria are not affected.
            </para>

            <para>
                Uninitialized persistent collections returned by the query are 
                not affected. Later, when the collection is initialized,
                entities loaded into the session will be read-only if 
                Session.isDefaultReadOnly() returns true.   
            </para>

            <para>
                Using <literal>Query.setReadOnly( true ) or
                <literal>Criteria.setReadOnly( true ) works well
                when a single HQL query or criteria loads all the entities and 
                intializes all the proxies and collections that the application
                needs to be read-only.
            </para>

            <para>
                When it is not possible to load and initialize all 
                necessary entities in a single query or criteria,
                you can temporarily change the session default to load
                entities as read-only before the query is executed.
                Then you can explicitly initialize proxies and collections 
                before restoring the session default.
            </para>

            <programlisting role="Java">
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
 
setDefaultReadOnly( true );
Contract contract = 
   ( Contract ) session.createQuery(
           "from Contract where customerName = 'Sherman'" )
           .uniqueResult();
Hibernate.initialize( contract.getPlan() );
Hibernate.initialize( contract.getVariations() );
Hibernate.initialize( contract.getNotes() );
setDefaultReadOnly( false );
...
tx.commit();
session.close();

</programlisting> 

            <para>
                If Session.isDefaultReadOnly() returns true, then you can
                use Query.setReadOnly( false ) and Criteria.setReadOnly( false )
                to override this session setting and load entities that are 
                not read-only.
            </para>

        </section>

        <section id="readonly-api-entity">
            <title>Making a persistent entity read-only
            <note>
                <para>
                    Persistent entities of immutable classes are automatically
                    made read-only.
                </para>
            </note>

            <para>
                To make a persistent entity or proxy read-only, call:
            </para> 
            <programlisting>Session.setReadOnly(entityOrProxy, true) 
 
            <para>
                To change a read-only entity or proxy of a mutable class so 
                it is no longer read-only, call:
            </para>
            <programlisting>Session.setReadOnly(entityOrProxy, false) 

            <important>
                <para>
                    When a read-only entity or proxy is changed so it is no longer 
                    read-only, Hibernate assumes that the current state of the 
                    read-only entity is consistent with its database representation. 
                    If this is not true, then any non-flushed changes made before
                    or while the entity was read-only, will be ignored.
                </para>
            </important>
            
            <para>        
                To throw away non-flushed changes and make the persistent entity 
                consistent with its database representation, call:           </para>
            <programlisting role="Java">session.refresh( entity );

            <para>
                To flush changes made before or while the entity
                was read-only and make the database representation 
                consistent with the current state of the persistent
                entity:
            </para>
<programlisting role="Java">
// evict the read-only entity so it is detached
session.evict( entity );

// make the detached entity (with the non-flushed changes) persistent
session.update( entity );

// now entity is no longer read-only and its changes can be flushed
s.flush();
</programlisting>
        </section>
    </section>

    <section id="readonly-proptypes">
        <title>Read-only affect on property type

        <para>
            The following table summarizes how different property types are 
            affected by making an entity read-only.
        </para>

        <table frame="topbot" id="readonly-proptype-summary">
            <title>Affect of read-only entity on property types
            <tgroup cols="2">        
                <colspec colwidth="1*"/>
                <colspec colwidth="1*"/>
                <thead>
                    <row>
                        <entry>Property/Association Type
                        <entry>Changes flushed to DB?
                    </row>
                </thead>
                <tbody>
                    <row>
                        <entry>
                            Simple
                            <para>
                                (<xref linkend="readonly-proptypes-simple"/>)
                            </para>
                        </entry>
                        <entry>no*
                    </row>
                    <row>
                        <entry>
                            <para>Unidirectional one-to-one 
                            <para>Unidirectional many-to-one 
                            <para>
                                (<xref linkend="readonly-proptypes-singleended-unidir"/>)
                            </para>
                        </entry>

                        <entry>
                            <para>no*
                            <para>no*
                        </entry>
                    </row>
                    <row>
                        <entry>
                            <para>Unidirectional one-to-many
                            <para>Unidirectional many-to-many
                            <para>
                                (<xref linkend="readonly-proptypes-manyended-unidir"/>)
                            </para>
                        </entry>
                        <entry>
                            <para>yes
                            <para>yes
                        </entry>
                   </row>
                    <row>
                        <entry>
                            <para>Bidirectional one-to-one
                            <para>
                                (<xref linkend="readonly-proptypes-onetoone-bidir"/>)
                            </para>
                        </entry>
                        <entry>only if the owning entity is not read-only*
                    </row>
                    <row>
                        <entry>
                            <para>Bidirectional one-to-many/many-to-one
                            <para>inverse collection
                            <para>non-inverse collection
                            <para>
                                (<xref linkend="readonly-proptypes-onetomany-manytoone"/>)
                            </para>
                        </entry>
                        <entry>
                            <para> 
                            <para>only added/removed entities that are not read-only*
                            <para>yes
                        </entry>
                    </row>
                    <row>
                        <entry>
                            <para>Bidirectional many-to-many
                            <para>
                                (<xref linkend="readonly-proptypes-manytomany-bidir"/>)
                            </para>
                        </entry>
                        <entry>yes
                    </row>
                </tbody>
            </tgroup>
        </table>
  
        <para>
            * Behavior is different when the entity having the property/association
              is read-only, compared to when it is not read-only.
        </para>

        <section id="readonly-proptypes-simple">
            <title>Simple properties

            <para>
                When a persistent object is read-only, Hibernate does not 
                dirty-check simple properties.
            </para>

            <para>
                Hibernate will not synchronize simple property state changes 
                to the database. If you have automatic versioning, Hibernate 
                will not increment the version if any simple properties change.
            </para>

	    <programlisting role="Java">
Session session = factory.openSession();
Transaction tx = session.beginTransaction();

// get a contract and make it read-only
Contract contract = ( Contract ) session.get( Contract.class, contractId );
session.setReadOnly( contract, true );

// contract.getCustomerName() is "Sherman"
contract.setCustomerName( "Yogi" );
tx.commit();

tx = session.beginTransaction();

contract = ( Contract ) session.get( Contract.class, contractId );
// contract.getCustomerName() is still "Sherman"
...
tx.commit();
session.close();
            </programlisting>

        </section>

        <section id="readonly-prop-types-unidir">
            <title>Unidirectional associations

            <section id="readonly-proptypes-singleended-unidir">
                <title>Unidirectional one-to-one and many-to-one

                <para>
                    Hibernate treats unidirectional one-to-one and many-to-one
                    associations in the same way when the owning entity is 
                    read-only. 
                </para>

                <para>
                    We use the term <emphasis>unidirectional single-ended 
                    association</emphasis> when referring to functionality
                    that is common to unidirectional one-to-one and many-to-one
                    associations.
                </para>

                <para>
                    Hibernate does not dirty-check unidirectional single-ended
                    associations when the owning entity is read-only. 
                </para>

                <para>
                    If you change a read-only entity's reference to a 
                    unidirectional single-ended association to null,
                    or to refer to a different entity, that change
                    will not be flushed to the database. 
                </para>

                <note>
                    <para>
                        If an entity is of an immutable class,
                        then its references to unidirectional single-ended
                        associations must be assigned when that 
                        entity is first created. Because the entity is
                        automatically made read-only, these references can
                        not be updated.
                    </para>
                </note>

                <para>
                    If automatic versioning is used, Hibernate will not 
                    increment the version due to local changes to 
                    unidirectional single-ended associations.
                </para>

                <para>
                    In the following examples, Contract has a unidirectional 
                    many-to-one association with Plan. Contract cascades save and
                    update operations to the association.
                </para>

                <para>
                    The following shows that changing a read-only entity's 
                    many-to-one association reference to null has no effect
                    on the entity's database representation.
                </para>

<programlisting role="Java">// get a contract with an existing plan;
// make the contract read-only and set its plan to null 
tx = session.beginTransaction();
Contract contract = ( Contract ) session.get( Contract.class, contractId );
session.setReadOnly( contract, true );
contract.setPlan( null );
tx.commit();

// get the same contract
tx = session.beginTransaction();
contract = ( Contract ) session.get( Contract.class, contractId );

// contract.getPlan() still refers to the original plan;

tx.commit();
session.close();</programlisting>

                <para>
                    The following shows that, even though
                    an update to a read-only entity's many-to-one 
                    association has no affect on the entity's 
                    database representation, flush still cascades 
                    the save-update operation to the locally
                    changed association.
                </para>

<programlisting role="Java">// get a contract with an existing plan;
// make the contract read-only and change to a new plan
tx = session.beginTransaction();
Contract contract = ( Contract ) session.get( Contract.class, contractId );
session.setReadOnly( contract, true );
Plan newPlan = new Plan( "new plan"
contract.setPlan( newPlan);
tx.commit();

// get the same contract
tx = session.beginTransaction();
contract = ( Contract ) session.get( Contract.class, contractId );
newPlan = ( Contract ) session.get( Plan.class, newPlan.getId() ); 

// contract.getPlan() still refers to the original plan;
// newPlan is non-null because it was persisted when 
// the previous transaction was committed; 

tx.commit();
session.close();</programlisting>

            </section>

            <section id="readonly-proptypes-manyended-unidir">
                <title>Unidirectional one-to-many and many-to-many

                <para>
                    Hibernate treats unidirectional one-to-many 
                    and many-to-many associations owned by a read-only
                    entity the same as when owned by an entity that is not 
                    read-only.
                </para>

                <para>
                    Hibernate dirty-checks unidirectional one-to-many and 
                    many-to-many associations;
                </para>

                <para>
                    The collection can contain entities that 
                    are read-only, as well as entities
                    that are not read-only.
                </para>

                <para> 
                    Entities can be added and removed from the
                    collection; changes are flushed to the database.
                </para>

                <para> 
                    If automatic versioning is used, Hibernate will 
                    update the version due to changes in the collection
                    if they dirty the owning entity.
                </para>

            </section>

        </section>

        <section id="readonly-proptypes-bidir">
            <title>Bidirectional associations

            <section id="readonly-proptypes-onetoone-bidir">
                <title>Bidirectional one-to-one

                <para>
                    If a read-only entity owns a bidirectional 
                    one-to-one association:
                </para>

                <itemizedlist>
                    <listitem>
                        <para>
                            Hibernate does not dirty-check the association. 
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            updates that change the association reference 
                            to null or to refer to a different entity
                            will not be flushed to the database. 
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            If automatic versioning is used, Hibernate will not 
                            increment the version due to local changes to 
                            the association.
                       </para>   
                    </listitem>
                </itemizedlist>

                <note>
                    <para>
                        If an entity is of an immutable class,
                        and it owns a bidirectional one-to-one
                        association, then its reference must be
                        assigned when that entity is first created. 
                        Because the entity is automatically made 
                        read-only, these references cannot be updated.
                    </para>   
                </note>

                <para>
                    When the owner is not read-only, Hibernate treats 
                    an association with a read-only entity the same
                    as when the association is with an entity that is
                    not read-only.
                </para>

            </section>

            <section id="readonly-proptypes-onetomany-manytoone">
                <title>Bidirectional one-to-many/many-to-one

                <para>
                    A read-only entity has no impact on a bidirectional
                    one-to-many/many-to-one association if:
                </para>

                <itemizedlist>
                    <listitem>
                        <para>
                            the read-only entity is on the one-to-many side
                            using an inverse collection;
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            the read-only entity is on the one-to-many side
                            using a non-inverse collection;                            
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            the one-to-many side uses a non-inverse collection 
                            that contains the read-only entity
                       </para>   
                    </listitem>
                </itemizedlist>

                <para>
                    When the one-to-many side uses an inverse collection:
                </para>

                <itemizedlist>
                    <listitem>
                        <para>
                            a read-only entity can only be added to the collection
                            when it is created;
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            a read-only entity can only be removed from the
                            collection by an orphan delete or by explicitly
                            deleting the entity.                            
                        </para>
                    </listitem>
                </itemizedlist>

            </section>

            <section id="readonly-proptypes-manytomany-bidir">
                <title>Bidirectional many-to-many
                <para>
                    Hibernate treats bidirectional many-to-many 
                    associations owned by a read-only entity the
                    same as when owned by an entity that is not
                    read-only.
                </para>

                <para>
                    Hibernate dirty-checks bidirectional many-to-many 
                    associations.
                </para>

                <para> 
                    The collection on either side of the association
                    can contain entities that are read-only, as well
                    as entities that are not read-only.
                </para>

                <para> 
                    Entities are added and removed from both sides 
                    of the collection; changes are flushed to the 
                    database.
                </para>

                <para> 
                    If automatic versioning is used, Hibernate will 
                    update the version due to changes in both sides of
                    the collection if they dirty the entity owning the
                    respective collections.
                </para>

            </section>

        </section>
    </section>
</chapter>

Other Hibernate examples (source code examples)

Here is a short list of links related to this Hibernate readonly.xml source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.