0

When I retrieve a Entity (row) with an intentionally unfetched many-to-one association and then try to update that Entity I get the famous transient instance error:

Error updating Object object references an unsaved transient instance - save the transient instance before flushing

But that "transient instance" was never fetched and so cannot even be transient

Code:

ProductFamily - java code

public class ProductFamily
{
    private Integer id;
    private Company company;
    private String name;

    //autogenerated getter & setter and constructors
}

ProductFamily - hbm.xml

<hibernate-mapping>
    <class name="package.ProductFamily" table="product_family" catalog="db">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <many-to-one name="company" class="package.Company" fetch="select">
            <column name="company" not-null="true"/>
        </many-to-one>
        <property name="name" type="string">
            <column name="name" length="64" not-null="true"/>
        </property>
    </class>
</hibernate-mapping>

Company - java code

public class Company
{
    private String name;
    private Set<ProductFamily> productFamilies = new HashSet<ProductFamily>(0);
    //autogenerated getter & setter and constructors
}

Company - hbm.xml

<!-- same header as above -->
<hibernate-mapping>
    <class name="package.Company" table="company" catalog="db">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <property name="name" type="string">
            <column name="name" length="64" not-null="true"/>
        </property>
        <set name="productFamilies" table="product_family" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="company" not-null="true"/>
            </key>
            <one-to-many class="package.ProductFamily" />
        </set>
    </class>
</hibernate-mapping>

test method simple retrieve and change and update

public void test()
{
    final StatelessSession session = this.sessionFactory.openStatelessSession();

    //get
    final ProductFamily productFamily = (ProductFamily)session.get(ProductFamily.class, 1);

    //change primitive property
    productFamily.setName(productFamily.getName() + "x");

    //update
    final Transaction tr = session.beginTransaction();

    try
    {
        session.update(productFamily);
        tr.commit();
    }
    catch (HibernateException e)
    {
        logger.severe(e.getMessage() + "\n" + e.getStackTrace());
        try
        {
            if(tr != null
                && tr.isActive())
                tr.rollback();
        }
        catch (HibernateException eTr)
        {
            logger.severe(eTr.getMessage() + "\n" + eTr.getStackTrace());
        }
    }
    finally
    {
        session.close();
    }
}
djmj
  • 5,579
  • 5
  • 54
  • 92

2 Answers2

0

I can't reproduce problem. Recreated project based on your code. Database - MySQL, Hibernate 4.1.1. Code works without exceptions.

So, here is link to my project. I decided to pack it with libraries I used (so you could check if problem appears with specific version of library).

build.xml contains 3 targets to start with predefined arguments (print, create and test).

Vadim Ponomarev
  • 1,346
  • 9
  • 15
  • Did you also used a stateless Session? Great Thanks for your investigation and time but I found the error or a bug. – djmj Apr 18 '12 at 01:19
  • Test method was copied from your question without changes. – Vadim Ponomarev Apr 18 '12 at 04:02
  • Even updated to hibernate 4.1.2 and still same error, regardless if I start the test method as a single application or withing running glassfish. Very strange changed all my StatelessSession's to Session's and it works again. – djmj Apr 18 '12 at 14:16
  • You can try to debug into hibernate source code. At least you will find out what exactly went wrong. – Vadim Ponomarev Apr 21 '12 at 18:29
0

The error is in the StatelessSession which I did not used before. Forgot to mention it.

djmj
  • 5,579
  • 5
  • 54
  • 92