在我的面向团队合作的应用程序中,我在用户和团队之间有多对多的关系,所以hibernate创建了关联表。问题是,在更新拥有团队的用户后,hibernate会从User_Team表中删除相应的关联记录。
用户实体:
@Entity
@Table(name="USERS")
public class User extends SelectItem {
@Id
@Column(name="EMAIL")
private String email;
@Column(name="PASSWORD")
private String password;
@Column(name="NAME")
private String name;
@Column(name="GROUPNAME")
private String group;
@ManyToMany(
targetEntity=Team.class
)
@ForeignKey(name="FK_TEAM_TO_USER", inverseName = "FK_USER_TO_TEAM")
@JoinTable(
name="USER_TEAM",
joinColumns=@JoinColumn(name="EMAIL"),
inverseJoinColumns=@JoinColumn(name="TEAMNAME")
)
@LazyCollection(LazyCollectionOption.FALSE)
private List<Team> teamList;
@OneToMany(
fetch = FetchType.EAGER,
mappedBy="user")
private List<Invitation> invitationList;
//getters setters
团队实体:
@Entity
@Table(name="TEAM")
public class Team extends SelectItem {
@Id
@Column(name="TEAMNAME")
private String name;
@ManyToOne
@ForeignKey(name="FK_TEAM_TO_TEAMLEADER")
@JoinColumn(name="TEAMLEADER")
private User teamLeader;
@ManyToMany(
mappedBy = "teamList",
targetEntity = User.class
)
@LazyCollection(LazyCollectionOption.FALSE)
private List<User> memberList;
//getters setters
这是日志:
信息:2012年11月20日22:50:0170 DEBUG org.hibernate.transaction.JDBCTransaction.begin:开始
信息:12年11月19日22:50:0015 DEBUG.org.hibernate.transaction.JDBCTrade.begin:current autocommit status:true
信息:12年12月20日22时50:0015hibernate.jdbc.util.SQLStatementLogger.log语句:从USERS user_中选择user_.EMAIL,user_.GROUPNAME作为GROUPNAME0_,user_.NAME作为NAME0_,user_.PASSWORD作为PASSWORD_,其中user_.EMIL=
信息:休眠:从USERS user_中选择user_.EMAIL,user_.GROUPNAME作为GROUPNAME0_,user_.NAME作为NAME0_,user_.PASSWORD作为PASSWORD_,其中user_.EMAIL=
信息:2012年11月20日22:50:0176 TRACE type.descriptor.sql.BasicBinder.bind:绑定参数[1]为[VARCHAR]-a@b.com
信息;2012年11日20日22:50:00177 TRACE type-descriptor.sql.BasicExtractor.extract:作为列[GROUPNAME0_]找到[users]
消息:2012年12月20日22时50:0178 TRACE type/descriptor.ssql.BasicExtract:作为列[NAME0_][default]找到TRACE type.descriptor.sql.BasicExtractor.extract:作为列[PASSWORD_]找到[默认]
信息:2012年11月20日22:50:0251 DEBUG org.hibernate.transaction.JDBCTransaction.commit:提交
信息:2012年12月20日22-50:0252 DEBUG hibernate.jdbc.util.SQLStatementLogger.log声明:更新USERS set GROUPNAME=?,NAME=?,密码=?其中电子邮件=
信息:休眠:更新USERS集GROUPNAME=?,NAME=?,密码=?其中电子邮件=
信息:2012年11月20日22:50:0260 TRACE type.descriptor.sql.BasicBinder.bind:绑定参数[1]为[VARCHAR]-用户
消息:2012年12月20日22时50:0261 TRACE type-descriptor.sql.BasicBindr.bind:绑定参数[2]为[VARCHAR]-andy
22:50:00262 TRACE type.descriptor.sql.BasicBinder.bind:绑定参数[4]为[VARCHAR]-a@b.com
信息:2012年11月20日22:50:00264调试hibernate.jdbc.util.SQLStatementLogger.log语句:从USER_TEAM中删除,其中EMAIL=
信息:休眠:从USER_TEAM中删除,其中EMAIL=
信息:2012年11月20日22:50:0271 TRACE type.descriptor.sql.BasicBinder.bind:将参数[1]绑定为[VARCHAR]-a@b.com
信息:2012年11月20日22:50:0274调试org.hubnate.transaction.JDBCTransaction.commit:已提交JDBC连接
更新操作由spring的hibernateTemplate在UserDAO:中的这个简单方法中提供
public void saveUser(User user){
hibernateTemplate.saveOrUpdate(user);
}
(我知道不应该使用hibernateTemplate,但我认为这不是这个问题的重点)
DAO方法在事务中简单地由spring服务bean UserServiceImpl:调用
@Transactional(readOnly=false)
public void saveUser(User user){
userDao.saveUser(user);
}
正如您所看到的,我没有任何级联注释,当然在更新中我也没有更改用户(EMAIL)的PK,所以我不理解这种行为。我使用的是spring3.1.0.RELEASE和hibernate 3.6.10.Final.
感谢您的建议或解释。
您不需要任何级联就可以实现这一点。给定用户的联接表的内容由该用户的teamList
集合的内容确定。因此,如果使用一个具有空团队列表的用户调用saveOrUpdate()
,Hibernate将删除该用户的联接表的内容。