Hibernate 3.6.10.Final ²Î¿¼ÊÖ²á ÖÐÎÄ°æ

Hibernate

Hibernate.org Community Documentation

重要

Hibernate's treatment of read-only entities may differ from what you may have encountered elsewhere. Incorrect usage may cause unexpected results.

  • Hibernate does not dirty-check the entity's simple properties or single-ended associations;

  • Hibernate will not update simple properties or updatable single-ended associations;

  • Hibernate will not update the version of the read-only entity if only simple properties or single-ended updatable associations are changed;

  • Hibernate cascades operations to associations as defined in the entity mapping.

  • Hibernate updates the version if the entity has a collection with changes that dirties the entity;

  • A read-only entity can be deleted.

  • It saves execution time by not dirty-checking simple properties or single-ended associations.

  • It saves memory by deleting database snapshots.

注意

Entities of immutable classes are automatically loaded as read-only.

Session.setDefaultReadOnly( true );
Session.setDefaultReadOnly( false );
Session.isDefaultReadOnly();
  • persistent entities already in the session when the default was changed

  • persistent entities that are refreshed via Session.refresh(); a refreshed persistent entity will only be read-only if it was read-only before refreshing

  • persistent entities added by the application via Session.persist(), Session.save(), and Session.update() Session.saveOrUpdate()

注意

Entities of immutable classes are automatically loaded as read-only.

Query.setReadOnly( true );
Criteria.setReadOnly( true );
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();

注意

Persistent entities of immutable classes are automatically made read-only.

Session.setReadOnly(entityOrProxy, true)
Session.setReadOnly(entityOrProxy, false)

重要

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.

session.refresh( entity );
// 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();
Property/Association Type Changes flushed to DB?
Simple

(第 12.2.1 节 “Simple properties”)

no*

Unidirectional one-to-one

no*

Unidirectional one-to-many

yes

Bidirectional one-to-one

only if the owning entity is not read-only*

Bidirectional one-to-many/many-to-one

only added/removed entities that are not read-only*

Bidirectional many-to-many

yes
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();
            

注意

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.

// 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();
// 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();
  • Hibernate does not dirty-check the association.

  • updates that change the association reference to null or to refer to a different entity will not be flushed to the database.

  • If automatic versioning is used, Hibernate will not increment the version due to local changes to the association.

注意

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.

  • the read-only entity is on the one-to-many side using an inverse collection;

  • the read-only entity is on the one-to-many side using a non-inverse collection;

  • the one-to-many side uses a non-inverse collection that contains the read-only entity

  • a read-only entity can only be added to the collection when it is created;

  • a read-only entity can only be removed from the collection by an orphan delete or by explicitly deleting the entity.