`
weishuwei
  • 浏览: 321945 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Hibernate Annotation级联操作不成功,求解?

阅读更多
1, 对象关系说明:
School对UserMember是一对多关系:
====================================================
2, 相关类说明:
----School类----
 
  1. private List<UserMember> users = new ArrayList<UserMember>();  
  2.   
  3. @OneToMany(mappedBy = "school",cascade = {CascadeType.PERSIST,CascadeType.REFRESH}, fetch = FetchType.LAZY, targetEntity =  
  4.   
  5. UserMember.class)  
  6. public List getUsers() {  
  7.     return users;  


----UserMember类----
 
  1. private School school;  
  2. @ManyToOne(cascade = { CascadeType.REFRESH},fetch=FetchType.LAZY)  
  3. @JoinColumn(name = "schoolId")  
  4. public SchoolInfo getSchool() {  
  5.     return school;  
  6. }  
  7.   
  8. //注意这里,郁闷的是双向关联时,关联的主键的insert,update操作必须设定为false  
  9. @Column(name = "schoolId", insertable = false, updatable = false, nullable = true, length = 36)  
  10. public String getSchoolId() {  
  11.     return this.schoolId;  
  12. }  

====================================================
3, 持久化操作:
备注:member1和member2都是新实例化的,并且注入有数据
 
  1. member1.setSchool(school);  
  2. member2.setSchool(school);  
  3.   
  4. List<UserMember> users=new ArrayList<UserMember>();  
  5. users.add(member1);  
  6. users.add(member2);  
  7. school.setUsers(users);  
  8. this.schoolService.create(this.school); 
====================================================
4, 问题:
1,本来预期上面操作会同时insert 2条用户信息到数据库,但结果是只插入了school信息.我把关联改为单向也不行.级联好像没起作用.求解????
2,我配置的为双向一对多关系,保存用户信息时,必须member.setSchool(school)才能保存进去数据,直接member.setSchoolId(" ");好像不行,求解????
分享到:
评论
7 楼 yongganzhe 2007-10-05  
我也遇到同样的问题了,解决方式:利用hibernate annotation的扩展标记@Cascade(CascadeType.SAVE_UPDATE)就ok了
6 楼 gky23 2007-08-22  
vffffffffffffffffff
5 楼 weishuwei 2007-08-17  
<div class='code_title'>to taya<br/>
</div>
<div class='dp-highlighter'>
<ol class='dp-j' start='1'>
    <li class='alt'><span><span>加了FetchType.LAZY好像读取user的时候就不会立即读取school啊   </span></span></li>
</ol>
</div>
确实是这样的,因为我并不打算在读取user信息同时获取school信息,而是通过传递schoolId参数查询相应school信息.
4 楼 taya 2007-08-15  
weishuwei 写道
经过测试,针对users的级联关系设置为CascadeType.ALL可以同步保存用户信息,为什么级联新建不可以???


请问这个问题找到原因了么?我对这个问题也很迷惑,找了好几天了都没找到答案

weishuwei 写道
一般情况下设置school属性确实没必要再设置schoolId属性了,但我查询user表时不希望加载用户信息,查看school信息完全可以通过schoolId来查询,这就是设置schoolId属性的原因.


加了FetchType.LAZY好像读取user的时候就不会立即读取school啊
我写了一段测试好像是这样的...
是不是你user对象里什么地方已经用到school了,所以才会触发对school的查询语句?
3 楼 weishuwei 2007-07-30  
To:打倒小日本
一般情况下设置school属性确实没必要再设置schoolId属性了,但我查询user表时不希望加载用户信息,查看school信息完全可以通过schoolId来查询,这就是设置schoolId属性的原因.
关于第二条确实必须设置user.setSchool(school);不然user的schoolId得不到值(除非指定值,但我是通过create(school)来同时创建user的),所以我的解决方式如下:
userMember类中:
public String getSchoolId() {
if(this.school!=null){
return this.school.getId();
}
return this.schoolId;
}
这样user.setSchool(school);就能为user传递schoolId,并且关系还是单向的,不必担心加载user时会加载school信息,同时读取user时,不用牵涉到关联对象也能获取到schoolId.

2 楼 打倒小日本 2007-07-28  
Hibernate Annotation的关联关系设置起来还是很简单的
User类
private School school;

@ManyToOne
@JoinColumn(name = "schoolId")
public School getSchool()
{
	return this.school;
}
public void setSchool(School school)
{
	this.school= school;
}


School类
private java.util.Set<User> users;

@OneToMany(mappedBy = "school")
public java.util.Set<User> getUsers()
{
	return this.users;
}
public void setUsers(java.util.Set<User> user)
{
	this.users= users;
}

===以上代码没经过测试===

再多说几句,关于原来楼主的写法
1、既然已经设置school属性了,就不要再设置schoolId属性了,他们是冲突的。
2、Hibernate Annotation默认OneToMany受控端(指定mappedBy = "school"即可),所以设置关联关系的话,必须为user.setSchool(school);
1 楼 weishuwei 2007-07-25  
继续接着上面的话题:
经过测试,针对users的级联关系设置为CascadeType.ALL可以同步保存用户信息,为什么级联新建不可以???

至于问题2的解决方式,我把双向关系改为单向了,但注解默认方式是通过关联表链接的,即我上面操作会生成insert school_userMember values ....语句,而我的关系是通过外键维护的,所以要加上@JoinColumn,如下:
@OneToMany @JoinColumn(name="schoolId");刚开始我以为@OneToMany的mappedBy属性指向的值必须是关联的对象,但要是去掉该属性后,关系就由school维护了,这样多产生了update userMember set schoolId=? where id=?语句,后来我把mappedBy指向UserMember的一个属性,发现也可以,即mappedBy = "schoolId",这样问题得以解决.

现在关系是单向一对多:
//member.setSchool(school);这个就不用了
member.setSchoolId("...");
List<UserMember> users=new ArrayList<UserMember>();
users.add(member); school.setUsers(users);
schoolService.create(this.school);

而只操作UserMember对象时,也不用涉及school了.

注:我一般把关系设置为单向一对多,关系由多的一方维护,一般情况项通过一可查询到多,而由多查一时,可以通过关联的外键来查询

相关推荐

Global site tag (gtag.js) - Google Analytics