[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-3230) getEntityName() throws org.hibernate.TransientObjectException: proxy was not associated with the session

Diego del Río (JIRA) noreply at atlassian.com
Thu Jan 20 11:11:05 EST 2011


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-3230?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=39711#action_39711 ] 

Diego del Río commented on HHH-3230:
------------------------------------

I made a TestCase, based on the class {{org.hibernate.junit.functional.FunctionalTestCase}} belonging to the package hibernate-testing, that reproduces the exception {{org.hibernate.TransientObjectException}} thrown in the method {{Session.getEntityName(String)}}. The test case, mapping files and entity classes are attached in [^NarrowingProxyTestCase.zip]

{noformat}

package org.headlesspigs.test;

import org.headlesspigs.domainmodel.Invoice;
import org.headlesspigs.domainmodel.WorkingPerson;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.TransientObjectException;
import org.hibernate.junit.functional.FunctionalTestCase;

public class ProxyNarrowingTest extends FunctionalTestCase {

        public ProxyNarrowingTest(String string) {
                super(string);
        }

	public String[] getMappings() {
		return new String[] { "Person.hbm.xml", "Invoice.hbm.xml" };
	}

	public String getBaseForMappings() {
		return "org/headlesspigs/domainmodel/";
	}

	public boolean createSchema() {
		return true;
	}

	public void testNarrowingProxy() throws Exception {
		Session s = null;
		Transaction tx = null;
		WorkingPerson p1 = null;
		WorkingPerson p2 = null;
		Invoice inv = null;
		try {
			s = this.openSession();
			tx = s.beginTransaction();
			p1 = new WorkingPerson("Adrian");
			p2 = new WorkingPerson("Batista", p1);
			inv = new Invoice("A-462", p1, p2);
			s.save(inv);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			throw e;
		} finally {
			if (s != null) {
				s.close();
			}
		}

		try {
			s = this.openSession();
			tx = s.beginTransaction();
			inv = (Invoice) s.load(Invoice.class, inv.getId());
			assertEquals("A-462", inv.getNumber());

			// The following line causes the proxy to the emitter Person to be
			// initialized. During this initialization, a proxy to
			// the referee person is found but its type is Person and not
			// WorkingPerson as needed, so Hibernate creates another proxy to
			// the referee, this time of type WorkingPerson, replacing the old
			// one.
			assertEquals("Batista", inv.getEmitter().getName());
			try {
				s.getEntityName(inv.getReceiver());
				fail("It should have thrown TransientObjectException");
			} catch (TransientObjectException e) {
				e.printStackTrace(System.err);
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			throw e;
		} finally {
			if (s != null) {
				s.close();
			}
		}
	}
}
{noformat}

{noformat}
package org.headlesspigs.domainmodel;


public class Invoice {
	private Long id;
	private int version;
	private String number;
	private Person receiver;
	private Person emitter;

	public Invoice() {
		super();
	}

	public Invoice(String number, Person receiver, Person emitter) {
		super();
		this.number = number;
		this.receiver = receiver;
		this.emitter = emitter;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public int getVersion() {
		return version;
	}

	public void setVersion(int version) {
		this.version = version;
	}

	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	public Person getReceiver() {
		return receiver;
	}

	public void setReceiver(Person receiver) {
		this.receiver = receiver;
	}

	public Person getEmitter() {
		return emitter;
	}

	public void setEmitter(Person emitter) {
		this.emitter = emitter;
	}

}
{noformat}

{noformat}
<?xml version="1.0" encoding="WINDOWS-1251"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.headlesspigs.domainmodel">

	<class name="Invoice" table="TEST_INVOICE">
		<id name="id" column="ID" type="long" unsaved-value="0">
			<generator class="native" />
		</id>
		<version name="version" column="VERSION" type="integer"></version>
		<property name="number" type="string" column="INVOICE_NUMBER"></property>
		<many-to-one name="emitter" class="Person" column="ID_EMITTER_PERSON"
			cascade="all">
		</many-to-one>
		<many-to-one name="receiver" class="Person" column="ID_RECEIVER_PERSON"
			cascade="all">
		</many-to-one>
	</class>
</hibernate-mapping>
{noformat}

{noformat}
package org.headlesspigs.domainmodel;


public class Person {
	private Long id;
	private int version;
	private String name;

	public Person() {
	}

	public Person(String name) {
		super();
		this.name = name;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public int getVersion() {
		return version;
	}

	public void setVersion(int version) {
		this.version = version;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}
{noformat}

{noformat}
package org.headlesspigs.domainmodel;

public class WorkingPerson extends Person {
	private WorkingPerson referee;

	public WorkingPerson() {
	}

	public WorkingPerson(String name) {
		super(name);
	}

	public WorkingPerson(String name, WorkingPerson referee) {
		this(name);
		this.referee = referee;
	}

	public WorkingPerson getReferee() {
		return referee;
	}

	public void setReferee(WorkingPerson referee) {
		this.referee = referee;
	}

}
{noformat}

{noformat}
<?xml version="1.0" encoding="WINDOWS-1251"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.headlesspigs.domainmodel">

	<class name="Person" table="TEST_PERSON">
		<id name="id" column="ID" type="long" unsaved-value="0">
			<generator class="native" />
		</id>
		<discriminator column="TYPE" type="string"/>
		<version name="version" column="VERSION" type="integer"></version>
		<property name="name" type="string" column="NAME"></property>
		<subclass name="WorkingPerson" discriminator-value="WORKING">
			<many-to-one name="referee" class="WorkingPerson" column="ID_REFEREE"></many-to-one>
		</subclass>
	</class>
</hibernate-mapping>
{noformat}

> getEntityName() throws org.hibernate.TransientObjectException: proxy was not associated with the session
> --------------------------------------------------------------------------------------------------------
>
>                 Key: HHH-3230
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3230
>             Project: Hibernate Core
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 3.2.2
>         Environment: Mac OS X, JDK 1.5
>            Reporter: Howard M. Lewis Ship
>         Attachments: Debugging output from IDEA.jpg, NarrowingProxyTestCase.zip
>
>
> I'm retrieving an entity that contains a OneToMany relationship.
> The master entity is retrieved, within a transaction, via Session.get(Class,Serializable).
> @Entity
> public class MapUnitSurvey extends ActiveDO
> {
>        @ManyToOne(fetch = FetchType.LAZY)
>     private VegetationType vegetationType;
> }
> @Entity
> public class VegetationType extends AbstractEnum
> {
> }
> ActiveDO and AbstractEnum are abstract base classes with @MappedSuperclass.
> I retrieve the vegationType:
>    VegetationType type = survey.getVegetationType();
> Then I need the type's entity name
> 	String entityName = session.getEntityName(type);
> 			
> This fails with the TransientObjectException.
> Inspecting with the debugger, I see that type is a CGLIB-enhanced proxy, and that there's a fully initialized bean in the target field of the proxy.  I'll attach a screenshot of some debugging data.
> In summary; the entity was retrieved via a lazy fetch, appears the be correct, seems to be in the session and yet the exception occurs.
> I've tried to resolve this by re-fetching the object from the session, and a few other tries, with no luck.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

       



More information about the hibernate-issues mailing list