-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: How does Session.evict() work?
PostPosted: Fri Jun 11, 2004 9:52 am 
Newbie

Joined: Mon Jan 12, 2004 7:05 am
Posts: 16
I have tried to use the evict and lock function to use objects in different sessions. and found some strange exceptions.
Here are my two tests, one with collection and another with persistent object as property. The code may make no sense, i have only tried to understand how evict and lock work.

Code:
                Configuration config = new Configuration().configure();
      SchemaUpdate su = new SchemaUpdate(config);
      su.execute(true);
      
      SessionFactory sfactory = config.buildSessionFactory();
      // save the objects in session one
      Session session = sfactory.openSession();
      Transaction tx = session.beginTransaction();
      
      Member m1 = new Member();
      Name n1 = new Name("Smith", "John");
      m1.setName(n1);
      m1.setEmail("John.Smith@hotmail.com");
      m1.setPassword("pw");
   
      Publication pub1 = new Publication();
      pub1.setTitle("Hibernate with Aspect");
      pub1.setData("blabla");
      pub1.setDate(new Date());
      
      Publication pub2 = new Publication();
      pub2.setTitle("Transaction with hibernate");
      pub2.setData("blabla");
      pub2.setDate(new Date());
      
      m1.setPublications(new HashSet());
      m1.getPublications().add(pub1);
      
      session.save(m1);
      tx.commit();
      session.close();
      
      // load object in session2
      Session session2 = sfactory.openSession();
      tx = session2.beginTransaction();
      String str = "select member from model.Member as member";
      Query q = session2.createQuery(str);
      Member m = (Member)q.list().iterator().next();
      //System.out.println(m.getPublications().size());
      session2.evict(m);
      
      session2.lock(m1, LockMode.UPGRADE);
      m1.getPublications().add(pub2);
      session2.update(m1);
      tx.commit();
      session2.close();


When i comment the System.out.println(m.getPublications().size(), it runs well, but with this code the following exception will be caused.
Code:
net.sf.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: 1, of class: model.Publication
   at net.sf.hibernate.impl.SessionImpl.checkUniqueness(SessionImpl.java:1600)
   at net.sf.hibernate.impl.SessionImpl.reassociate(SessionImpl.java:1606)
   at net.sf.hibernate.impl.SessionImpl.lock(SessionImpl.java:1631)
   at net.sf.hibernate.engine.Cascades$2.cascade(Cascades.java:79)
   at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
   at net.sf.hibernate.engine.Cascades.cascadeCollection(Cascades.java:526)
   at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:452)
   at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
   at net.sf.hibernate.impl.SessionImpl.lock(SessionImpl.java:1635)
   at mytest.EvictTest.main(EvictTest.java:129)
Exception in thread "main"

but in the debug i can see, the collection will be evicted.
Code:
14:57:03,746 DEBUG SessionImpl:3485 - evicting [model.Member]
14:57:03,746 DEBUG SessionImpl:3512 - evicting collection: [model.Member.publications#1]



Next test works with address property of a member object. it is also a persistent object.
Code:
                Configuration config = new Configuration().configure();
      SchemaUpdate su = new SchemaUpdate(config);
      su.execute(true);
      
      SessionFactory sfactory = config.buildSessionFactory();
      // save the objects in session one
      Session session = sfactory.openSession();
      
      Transaction tx = session.beginTransaction();
      
      Member m1 = new Member();
      Name n1 = new Name("Smith", "John");
      m1.setName(n1);
      m1.setEmail("John.Smith@hotmail.com");
      m1.setPassword("pw");
      Address adr1 = new Address("john_home", "1", new Integer(60599),
            "Frankfurt", "Germany");
      m1.setAddress(adr1);
      
      Publication pub1 = new Publication();
      pub1.setTitle("Hibernate with Aspect");
      pub1.setData("blabla");
      pub1.setDate(new Date());
      
      m1.setPublications(new HashSet());
      m1.getPublications().add(pub1);
   
      pub1.setMembers(new HashSet());
      pub1.getMembers().add(m1);
      
      session.save(m1);
      tx.commit();
      session.close();
      
      Session session2 = sfactory.openSession();
      tx = session2.beginTransaction();
      String str = "select member from model.Member as member";
      Query q = session2.createQuery(str);
      Collection ps = q.list();
      Member m = (Member)ps.iterator().next();
      m.getAddress().setCity("Shanghai");
      session2.update(m);
      tx.commit();
      session2.evict(m);
      
      tx = session2.beginTransaction();
      session2.lock(m1, LockMode.UPGRADE);
      System.out.println(m1.getAddress().getCity());
      session2.update(m1);
      tx.commit();
      session2.close();

the following exception will be caused.
Code:
net.sf.hibernate.HibernateException: cannot lock an unsaved transient instance: [model.Address]
   at net.sf.hibernate.impl.SessionImpl.lock(SessionImpl.java:1629)
   at net.sf.hibernate.engine.Cascades$2.cascade(Cascades.java:79)
   at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
   at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
   at net.sf.hibernate.impl.SessionImpl.lock(SessionImpl.java:1635)
   at mytest.EvictTest.main(EvictTest.java:77)
Exception in thread "main"

After the test was run, In the database will 2 address datasets inserted. One with city Frankfurt and another with city Shanghai.

Here is my mapping document
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
                                   "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>

   <class name="model.Address" table="ADDRESS" select-before-update="true">
      <id name="id" type="long" unsaved-value="any">
         <column name="ADDRESS_ID" not-null="true" />
         <generator class="native" />
      </id>
      <property name="street">
         <column name="street" not-null="false" />
      </property>
      <property name="number">
         <column name="number" not-null="false" />
      </property>
      <property name="zip">
         <column name="zip" not-null="false" />
      </property>
      <property name="city">
         <column name="city" not-null="false" />
      </property>
      <property name="country">
         <column name="country" not-null="false" />
      </property>
      <many-to-one update="false" insert="false" name="person" class="model.Person" column="PERSON_ID" unique="true" cascade="save-update" />
   </class>
   
   <class name="model.Cat" table="CAT" select-before-update="true">
      <id name="id" type="long" unsaved-value="any">
         <column name="CAT_ID" not-null="true" />
         <generator class="native" />
      </id>
      <property name="name">
         <column name="name" not-null="false" />
      </property>
      <property name="sex">
         <column name="sex" not-null="false" />
      </property>
      <property name="weight">
         <column name="weight" not-null="false" />
      </property>
   </class>

    <class name="model.Person" table="PERSON">
    <id name="id" type="long" unsaved-value="null">
      <column name="PERSON_ID" not-null="true" />
      <generator class="native" />
    </id>
    <discriminator column="type" type="string" />
    <component class="model.Name" name="name">
      <property name="forename">
        <column name="forename" not-null="false" />
      </property>
      <property name="surname">
        <column name="surname" not-null="false" />
      </property>
    </component>
    <many-to-one cascade="all" class="model.Cat" column="CAT_ID" name="cat" unique="true" />
    <list name="sizes" table="PERSON_SIZES">
      <key column="PERSON_ID" />
      <index column="I" />
      <element column="sizes" type="string" />
    </list>
    <!--
    <list name="phones" table="PERSON_PHONES">
      <key column="PERSON_ID" />
      <index column="I" />
      <composite-element class="model.Phone" name="phones">
        <property name="prefix">
          <column name="prefix" not-null="false" />
        </property>
        <property name="number">
          <column name="number" not-null="false" />
        </property>
      </composite-element>
    </list>
    -->
    <many-to-one cascade="all" class="model.Address" column="ADDRESS_ID" name="address" unique="true" />
   <subclass name="model.Member" extends="model.Person">
      <property name="email">
        <column name="email" not-null="false" />
      </property>
      <property name="password">
        <column name="password" not-null="false" />
      </property>
      <set name="publications" table="Publication_Member" lazy="true" cascade="save-update">
        <key>
          <column name="Member_ID" not-null="true" />
        </key>
        <many-to-many class="model.Publication">
          <column name="Publication_ID" not-null="true" />
        </many-to-many>
      </set>
    </subclass>
    <subclass extends="model.Person" name="model.SeminarParticipant">
      <property name="department">
        <column name="department" not-null="false" />
      </property>
      <property name="email">
        <column name="email" not-null="false" />
      </property>
      <many-to-one cascade="save-update" column="SEMINARTOPIC_ID" insert="false" name="seminarTopic" update="false" />
      <many-to-one cascade="save-update" column="SEMINAR_ID" insert="false" name="seminar" update="false" />
      <property name="matriculationNo">
        <column name="matriculationNo" not-null="false" />
      </property>
    </subclass>
    </class>
   
    <class name="model.Seminar" table="SEMINAR">
       <id name="id" type="long" unsaved-value="null">
          <column name="SEMINAR_ID" not-null="true" />
          <generator class="native" />
       </id>
       <property name="title">
          <column name="title" not-null="false" />
       </property>
       <property name="description">
          <column name="description" not-null="false" />
       </property>
       <many-to-one name="semester" column="SEMESTER_ID" insert="false" update="false" cascade="save-update" />
       <many-to-one name="member" class="model.Member" column="MEMBER_ID" unique="true" cascade="save-update" />
       <list name="seminarTopics" lazy="true" cascade="all">
          <key column="SEMINAR_ID" />
          <index column="I" />
          <one-to-many class="model.SeminarTopic" />
       </list>
       <list name="seminarParticipants" lazy="true" cascade="save-update">
          <key column="SEMINAR_ID" />
          <index column="I" />
          <one-to-many class="model.SeminarParticipant" />
       </list>
    </class>
   
    <class name="model.SeminarTopic" table="SEMINARTOPIC">
       <id name="id" type="long" unsaved-value="null">
       <column name="SEMINARTOPIC_ID" not-null="true" />
       <generator class="native" />
       </id>
       <property name="title"><column name="title" not-null="false" /></property>
       <property name="description"><column name="description" not-null="false" /></property>
       <property name="data"><column name="data" not-null="false" /></property>
       <list name="seminarParticipants" lazy="true" cascade="save-update">
          <key column="SEMINARTOPIC_ID" />
          <index column="I" />
          <one-to-many class="model.SeminarParticipant" />
       </list>
    </class>
   
    <class name="model.Semester" table="SEMESTER">
       <id name="id" type="long" unsaved-value="null">
       <column name="SEMESTER_ID" not-null="true" />
       <generator class="native" />
       </id>
       <property name="description">
          <column name="description" not-null="false" /></property>
       <property name="starts"><column name="starts" not-null="false" /></property>
       <property name="ends"><column name="ends" not-null="false" /></property>
       <set name="seminars" lazy="true" cascade="all">
          <key column="SEMESTER_ID" />
          <one-to-many class="model.Seminar" />
       </set>
    </class>
   
    <class name="model.Publication" table="PUBLICATION" polymorphism="implicit">
       <id name="id" type="long" unsaved-value="null">
       <column name="PUBLICATION_ID" not-null="true" />
       <generator class="native" />
       </id>
       <discriminator column="DiscriminatorType" type="string" />
       <property name="title"><column name="title" not-null="false" /></property>
       <property name="date"><column name="date" not-null="false" /></property>
       <property name="data"><column name="data" not-null="false" /></property>
       <set name="members" table="Member_Publication" lazy="true" cascade="save-update">
       <key><column name="Publication_ID" not-null="true" /></key>
       <many-to-many class="model.Member"><column name="Member_ID" not-null="true" />
       </many-to-many>
       </set>
    </class>
</hibernate-mapping>


Code for model classes
Code:
/*
* Created on 2004-1-27
*/
package model;

/**
* @author Xiaoying Wu
*/
public class Address extends PersistentRoot{

   private String street;

   private String number;

   private Integer zip;

   private String city;

   private String country;
   
   private Person person;
   
   public Address(){
      super();
   }
   
   public Address(String s, String n, Integer z, String c, String co){
      street = s;
      number = n;
      zip = z;
      city = c;
      country = co;
   }

   public String getStreet() {
      return street;
   }

   public void setStreet(String s){
      street = s;
   }

   public String getNumber() {
      return number;
   }

   public void setNumber(String n){
      number = n;
   }

   public Integer getZip(){
      return zip;
   }
   
   public void setZip(Integer z){
      zip = z;
   }
   
   public String getCity() {
      return city;
   }

   public void setCity(String c){
      city = c;
   }

   public String getCountry() {
      return country;
   }

   public void setCountry(String c){
      country = c;
   }
   
   public Person getPerson(){
      return person;
   }
   
   public void setPerson(Person p){
      person = p;
   }

}


Code:
/*
* Created on 2004-1-6
*/
package model;

import java.util.List;

/**
* @author Xiaoying Wu
*/
public class Person extends PersistentRoot{

   private Name name;

   //private List adresses;
   private Cat cat_$CD;

   //private Set addresses_$model_Address;
   
   private List sizes_$CL_java_lang_String;
   
   private List phones_$CL_model_Phone;
   
   /** home address */
   private Address address_$CD;
   

   //Each Persistent Class must have a constructor without parameter.
   public Person(){
      super();
   }

   public Person(Name n){
      name = n;
   }
   
   public Person(Cat c){
      this.cat_$CD = c;
   }
   
   public Name getName(){
      return name;
   }
   
   public void setName(Name n){
      this.name = n;
   }

   //public void setAddresses(Set addresses) {
   //   addresses_$model_Address = addresses;
   //}

   //public Set getAddresses() {
   //   return addresses_$model_Address;
   //}

   public Cat getCat() {
      return cat_$CD;
   }

   public void setCat(Cat c){
      cat_$CD = c;
   }
   
   public List getSizes(){
      return sizes_$CL_java_lang_String;
   }
   
   public void setSizes(List s){
      sizes_$CL_java_lang_String = s;
   }

   public Address getAddress() {
      return address_$CD;
   }
   
   public void setAddress(Address a){
      address_$CD = a;
   }
      
   
   /*
   public List getAddresses(){
      return addresses;
   }
   
   public void setAddresses(List as){
      this.addresses = as;
   }*/
   
   /*public List getNames(){
      return names_$model_Name;
   }
   
   public void setNames(List names){
      names_$model_Name = names;
   }*/
   
   public List getPhones(){
      return phones_$CL_model_Phone;
   }
   
   public void setPhones(List phones){
      phones_$CL_model_Phone = phones;
   }

}


Code:
package model;

import java.util.Set;


/**
* @author xiaoying
*
* Persistent Class Member
*/
public class Member extends Person{

   //private Name name;

   private String email;

   private String password;

   //private List seminars;

   private Set publications_$CL_model_Publication;

   public Member(){
      super();
   }
   
   public Set getPublications() {
      return publications_$CL_model_Publication;
   }

   public void setPublications(Set ps){
      this.publications_$CL_model_Publication = ps;
   }

   //public List getSeminars(){
   //   return seminars;
   //}

   //public void setSeminars(List s){
   //   this.seminars = s;
   //}

   public String getEmail() {
      return email;
   }

   public String getPassword() {
      return password;
   }

   public void setEmail(String e){
      this.email = e;
   }

   public void setPassword(String p){
      this.password = p;
   }

   /*
   public Name getName() {
      return name;
   }

   public void setName(Name n) {
      this.name = n;
   }
   */
}


Code:
package model;

import java.util.Date;
import java.util.Set;

/**
* @author xiaoying
*/
public class Publication extends PersistentRoot{

   private String title;

   private Date date;

   private String data;
   
   private Set members_$CL_model_Member;
   
   public Publication(){
      super();
   }
   
   public Set getMembers(){
      return members_$CL_model_Member;
   }
   
   public void setMembers(Set ms){
      this.members_$CL_model_Member = ms;
   }

   public String getTitle() {
      return title;
   }

   public Date getDate() {
      return date;
   }

   public String getData() {
      return data;
   }

   public void setTitle(String t){
      this.title = t;
   }

   public void setDate(Date d){
      this.date = d;
   }

   public void setData(String b){
      this.data = b;
   }

}


Code:
/*
* Created on 2004-6-3
*/
package model;

/**
* @author Xiaoying Wu
*/
public class PersistentRoot {
   
   private Long id;
   
   
   /**
    * @return Returns the id.
    */
   public Long getId() {
      return id;
   }
   /**
    * @param id The id to set.
    */
   public void setId(Long id) {
      this.id = id;
   }
}


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 14, 2004 11:16 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Can you simplify your test case, it'll be easier to answer.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 14, 2004 12:31 pm 
Newbie

Joined: Mon Jan 12, 2004 7:05 am
Posts: 16
OK, this is a simplified version. :-)

In the tests i try to insert a member object at first, and load it from the database into another object, and then evict the new object, and reuse the original member object with lock function. The first test handles a one-to-many relation and second test a one-to-one relation.
Code:
      Session session = sfactory.openSession();
      Transaction tx = session.beginTransaction();

      // member has one-to-many relation to publication
      Member member = new Member("smith");

      Publication pub1 = new Publication("first publication");       
      Publication pub2 = new Publication("second publication");
     
      member.setPublications(new HashSet());
      member.getPublications().add(pub1);
       
      session.save(m1);
      tx.commit();
      session.close();
       
      // load member in session2
      Session session2 = sfactory.openSession();
      tx = session2.beginTransaction();
      String str = "select member from model.Member as member";
      Query q = session2.createQuery(str);
      Member m = (Member)q.list().iterator().next();
      //System.out.println(m.getPublications().size());
      session2.evict(m);
     
      // lock the original object member
      session2.lock(member, LockMode.UPGRADE);
      m1.getPublications().add(pub2);
      session2.update(member);
      tx.commit();
      session2.close();

When i comment the System.out.println(m.getPublications().size(), it runs well, but with this code the following exception occurs.

Code:
net.sf.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: 1, of class: model.Publication
   at net.sf.hibernate.impl.SessionImpl.checkUniqueness(SessionImpl.java:1600)
   at net.sf.hibernate.impl.SessionImpl.reassociate(SessionImpl.java:1606)
   at net.sf.hibernate.impl.SessionImpl.lock(SessionImpl.java:1631)
   at net.sf.hibernate.engine.Cascades$2.cascade(Cascades.java:79)
   at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
   at net.sf.hibernate.engine.Cascades.cascadeCollection(Cascades.java:526)
   at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:452)
   at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
   at net.sf.hibernate.impl.SessionImpl.lock(SessionImpl.java:1635)
   at mytest.EvictTest.main(EvictTest.java:129)
Exception in thread "main"



Test2
Code:
      Session session = sfactory.openSession();
      Transaction tx = session.beginTransaction();
       
      Member member = new Member("smith");
      Address adr1 = new Address("john_home", "1", new Integer(60599),
            "Frankfurt", "Germany");
      m1.setAddress(adr1);
             
      session.save(m1);
      tx.commit();
      session.close();
       
      Session session2 = sfactory.openSession();
      tx = session2.beginTransaction();
      String str = "select member from model.Member as member";
      Query q = session2.createQuery(str);
      Member m = (Member)q.list().iterator().next();
      m.getAddress().setCity("Shanghai");
      session2.update(m);
      tx.commit();
      session2.evict(m);
       
      tx = session2.beginTransaction();
      session2.lock(member, LockMode.UPGRADE);
      System.out.println(member.getAddress().getCity());
      session2.update(member);
      tx.commit();
      session2.close();


This Test occurs the following exception
Code:
net.sf.hibernate.HibernateException: cannot lock an unsaved transient instance: [model.Address]
   at net.sf.hibernate.impl.SessionImpl.lock(SessionImpl.java:1629)
   at net.sf.hibernate.engine.Cascades$2.cascade(Cascades.java:79)
   at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
   at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
   at net.sf.hibernate.impl.SessionImpl.lock(SessionImpl.java:1635)
   at mytest.EvictTest.main(EvictTest.java:77)
Exception in thread "main"


I hope these tests are easy to understand this time. Thx for the patient.
:-)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 14, 2004 6:03 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
NonUniqueObject
Remeber that a member has publications, and those publication are shared between the 2 members, It should be the same instance of publisher to attach it to the session.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 15, 2004 4:37 am 
Newbie

Joined: Mon Jan 12, 2004 7:05 am
Posts: 16
In mein first test i have inserted only one member, the publications will not be shared among many members. The first member object, that I have created has references of the publications, and the m object, that I have loaded from the database, may have also references of the same publications, but after I've evicted the m object, it should have no more the references of the publications.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.