帮助理解hibernate行为/错误

时间:2011-02-24 03:09:42

标签: java hibernate

我有一个Product类,它与自身有一对多的关联(复合模式)。下面分别是pojo,hbm,测试代码和日志/错误。有人可以解释这个错误是什么。为什么在设置父主键时出现此错误?

产品pojo

public class Product
{
    private Long id;

    private Set<Product> children = Collections.emptySet();

    public void addChild(final Product child)
    {
        if (children.isEmpty())
        {
            children = Sets.newHashSet();
        }
        child.setParent(this);
        children.add(child);
    }
}

的hbm.xml

<class name="Product" table="PRODUCT">
        <set name="children" lazy="false" table="PRODUCT">
            <key>
                <column name="ID" />
            </key>
            <one-to-many class="Product" />
        </set>
</class>

测试

public void save()
    {
        // Level 1 - mortgage LOB
        Product mortgage = new Product();
        mortgage.setCode("Mortgage");

        Product ml = new Product();
        ml.setCode("Mortgage Loan");

        Product me = new Product();
        me.setCode("Home Equity LOC");

        //Level 2
        mortgage.addChild(ml);
        mortgage.addChild(me);

        hibernateTemplate.save(mortgage);
    }

记录和错误

DEBUG [org.hibernate.SQL] insert into PRODUCT (ID, CODE, NAME, STARTDATE, ENDDATE, ISDECISIONABLE, ISSELECTABLE) values (null, ?, ?, ?, ?, ?, ?)
DEBUG [org.hibernate.type.StringType] binding 'Mortgage' to parameter: 1
DEBUG [org.hibernate.type.StringType] binding null to parameter: 2
DEBUG [org.hibernate.type.TimestampType] binding null to parameter: 3
DEBUG [org.hibernate.type.TimestampType] binding null to parameter: 4
DEBUG [org.hibernate.type.BooleanType] binding 'false' to parameter: 5
DEBUG [org.hibernate.type.BooleanType] binding 'false' to parameter: 6
DEBUG [org.hibernate.SQL] call identity()
DEBUG [org.hibernate.SQL] update PRODUCT set ID=? where ID=?
DEBUG [org.hibernate.type.LongType] binding '1' to parameter: 1
ERROR [org.hibernate.event.def.AbstractFlushingEventListener] Could not synchronize database state with session
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.Product
    at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:219)
    at org.hibernate.type.EntityType.getIdentifier(EntityType.java:397)
    at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:78)

2 个答案:

答案 0 :(得分:4)

瞬态对象是尚未保存的对象。如图所示,您的关系不会使用任何“传递持久性”,也就是说,您没有告诉hibernate,当您保存父级时,您要保存子级。我猜这个错误是因为你在父节点(在会话中)有子节点的实例(无论子节点具有相同类的父节点),并且hibernate知道这一点,但它不知道怎么处理他们。

你可以:

1)在保存父母之前保存孩子 2)在映射中添加'cascade'属性,例如cascade =“save”或cascade =“all”

请参阅http://docs.jboss.org/hibernate/core/3.3/reference/en/html/objectstate.html#objectstate-transitive

答案 1 :(得分:0)

嗯,我不认为这就是你的所有代码?因为在你的pojo中你需要为你的Set设置getter和setter。并尝试以这种方式传播产品:

Set children=new HashSet();
Product p=new Product(); 
Product p1=new Product(); 
Product p2=new Product();
children.add(p1);
children.add(p2);
p.setChildren(children);
hibernateTemplate.save(p);

但是把cascade =&#34; all&#34;或级联=&#34;保存更新&#34;在你的集合映射中。