【问题标题】:hibernate StatelessSession update with many-to-one not working (transient instance)?休眠状态无会话更新与多对一不工作(瞬态实例)?
【发布时间】:2012-04-28 01:00:45
【问题描述】:

当我检索具有故意未提取的多对一关联的实体(行)然后尝试更新该实体时,我得到了著名的瞬态实例错误:

更新对象时出错 对象引用了一个未保存的瞬态实例 - 在刷新之前保存瞬态实例

但是那个“瞬态实例”从未被获取,因此甚至不能是瞬态的

代码:

ProductFamily - java 代码

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>

公司 - java 代码

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

公司 - 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>

测试方法简单检索、更改和更新

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

【问题讨论】:

  • 请出示您的代码。关于故意未获取的关联、实体修改和“更新”的部分。
  • 我添加了一个简化的示例,但仍然产生相同的错误。

标签: hibernate foreign-keys fetch transient


【解决方案1】:

我无法重现问题。根据您的代码重新创建项目。数据库 - MySQL,Hibernate 4.1.1。代码无异常运行。

所以,这里是link to my project。我决定将它与我使用的库一起打包(这样您就可以检查特定版本的库是否出现问题)。

build.xml 包含 3 个以预定义参数开头的目标(printcreatetest)。

【讨论】:

  • 你是否也使用了无状态会话?非常感谢您的调查和时间,但我发现了错误或错误。
  • 测试方法是从您的问题中复制的,没有更改。
  • 即使更新到休眠 4.1.2 仍然出现同样的错误,无论我是作为单个应用程序启动测试方法还是运行 glassfish。很奇怪将我所有的 StatelessSession 都更改为 Session 的,它又可以工作了。
  • 你可以尝试调试到hibernate源码中。至少你会发现到底出了什么问题。
【解决方案2】:

错误出现在我之前没有使用过的 StatelessSession 中。忘记说了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-20
    • 2019-03-28
    • 2020-01-11
    • 2020-02-16
    • 1970-01-01
    • 1970-01-01
    • 2020-03-08
    相关资源
    最近更新 更多