Hibernate自身双向一对多关联。异常:object references an unsaved transient instance

1、建表,很简单的3个字段。

主键,name,外键指向自身id

CREATE TABLE `NewTable` (
`id`  int(11) NOT NULL AUTO_INCREMENT ,
`name`  varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`category_id`  int(11) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
FOREIGN KEY (`category_id`) REFERENCES `category` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
INDEX `category_id` (`category_id`) USING BTREE
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
AUTO_INCREMENT=1
ROW_FORMAT=COMPACT
;

2、类以及映射文件。

public class Category implements java.io.Serializable {

	// Fields

	private Integer id;
	private Category category;
	private String name;
	private Set categories = new HashSet(0);

	// Constructors

	/** default constructor */
	public Category() {
	}

	/** minimal constructor */
	public Category(Category category) {
		this.category = category;
	}

	/** full constructor */
	public Category(Category category, String name, Set categories) {
		this.category = category;
		this.name = name;
		this.categories = categories;
	}

	// Property accessors

	public Integer getId() {
		return this.id;
	}

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

	public Category getCategory() {
		return this.category;
	}

	public void setCategory(Category category) {
		this.category = category;
	}

	public String getName() {
		return this.name;
	}

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

	public Set getCategories() {
		return this.categories;
	}

	public void setCategories(Set categories) {
		this.categories = categories;
	}

}

然后是映射文件。 来看看几种不同的配置会有怎样的效果

1、最初是这样写的:


<hibernate-mapping>
    <class name="modle.Category" table="category" catalog="h_01">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <many-to-one name="category" class="modle.Category" fetch="select">
            <column name="category_id"  />
        </many-to-one>
        <property name="name" type="java.lang.String">
            <column name="name" length="50" />
        </property>
        <set name="categories">
            <key>
                <column name="category_id"  />
            </key>
            <one-to-many class="modle.Category" />
        </set>
    </class>
</hibernate-mapping>

测试代码:

		Category c1 = new Category();
		c1.setCategories(new HashSet());
		c1.setCategory(null);
		c1.setName("c1");
		
		Category c2 = new Category();
		c2.setCategory(c1);
		
		c2.setName("c2");
		c2.setCategories(null);
		
		c1.getCategories().add(c2);
		Session session = HibernateSessionFactory.getSession();
		Transaction tran = session.beginTransaction();
		
		session.save(c1);
		System.out.println(c1.getId());
		
		tran.commit();
		session.close();

出现了下面的错误:应该是保存顺序导致,怎么还有一个update语句呢? 请高手解答!


Hibernate: insert into h_01.category (category_id, name) values (?, ?)
14
Hibernate: update h_01.category set category_id=? where id=?
Exception in thread "main" org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: modle.Category
	at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:242)
	at org.hibernate.type.EntityType.getIdentifier(EntityType.java:430)
	at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:101)
	at org.hibernate.persister.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:777)
	at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1165)

2、然后改下配置文件 添加一个cascade

 <set name="categories" cascade="save-update">
            <key>
                <column name="category_id"  />
            </key>
            <one-to-many class="modle.Category" />
        </set>

执行正确,但是有3条语句。

Hibernate: insert into h_01.category (category_id, name) values (?, ?)
Hibernate: insert into h_01.category (category_id, name) values (?, ?)
15
Hibernate: update h_01.category set category_id=? where id=?

3、再改下,加上inverse 。 这个其实就是用反向工程自动生成的。(反向工程还是很好用滴!!)

<set name="categories" inverse="true" cascade="save-update">
            <key>
                <column name="category_id"  />
            </key>
            <one-to-many class="modle.Category" />
        </set>
这就对了,应该是两条语句。
Hibernate: insert into h_01.category (category_id, name) values (?, ?)
Hibernate: insert into h_01.category (category_id, name) values (?, ?)
17



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值