更新后,Hibernate会从多对多关联表中删除记录

pau*_*ook 2 many-to-many hibernate cascading-deletes hibernate-annotations hibernate-cascade

在我的团队合作应用程序中,我在用户和团队之间有多对多的关系,因此hibernate创建了关联表.问题是,在更新具有Team的User后,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
Run Code Online (Sandbox Code Playgroud)

团队实体:

@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
Run Code Online (Sandbox Code Playgroud)

这是日志:

信息:20.11.2012 22:50:00,170 DEBUG org.hibernate.transaction.JDBCTransaction.begin:begin
INFO:20.11.2012 22:50:00,175 DEBUG org.hibernate.transaction.JDBCTransaction.begin:current autocommit status:true
INFO: 20.11.2012 22:50:00,175 DEBUG org.hibernate.transaction.JDBCTransaction.begin:禁用自动提交
信息:20.11.2012 22:50:00,175 DEBUG hibernate.jdbc.util.SQLStatementLogger.logStatement:select user_.EMAIL,user_.GROUPNAME作为GROUPNAME0_,user_.NAME为NAME0_,user_.PASSWORD为来自USERS user_的PASSWORD0_,其中user_.EMAIL =?
INFO:Hibernate:从USERS user_中选择user_.EMAIL,user_.GROUPNAME为GROUPNAME0_,user_.NAME为NAME0_,user_.PASSWORD为PASSWORD0_,其中user_.EMAIL =?
INFO:20.11.2012 22:50:00,176 TRACE type.descriptor.sql.BasicBinder.bind:binding parameter [1] as [VARCHAR] - a@b.com
INFO:20.11.2012 22:50:00,177 TRACE type.descriptor .sql.BasicExtractor.extract:找到[users]列[GROUPNAME0_]
INFO:20.11.2012 22:50:00,178 TRACE type.descriptor.sql.BasicExtractor.extract:found [default] as column [NAME0_]
INFO:20.11. 2012 22:50:00,178 TRACE type.descriptor.sql.BasicExtractor.extract:found [default] as column [PASSWORD0_]
INFO:20.11.2012 22:50:00,251 DEBUG org.hibernate.transaction.JDBCTransaction.commit:commit
INFO: 20.11.2012 22:50:00,252 DEBUG hibernate.jdbc.util.SQLStatementLogger.logStatement:更新USERS设置GROUPNAME =?,NAME =?,PASSWORD =?哪里有EMAIL =?
信息:休眠:更新USERS设置GROUPNAME =?,NAME =?,PASSWORD =?哪里有EMAIL =?
信息:20.11.2012 22:50:00,260 TRACE type.descriptor.sql.BasicBinder.bind:binding parameter [1] as [VARCHAR] - users
INFO:20.11.2012 22:50:00,261 TRACE type.descriptor.sql.BasicBinder .bind:binding parameter [2] as [VARCHAR] - andy
INFO:20.11.2012 22:50:00,261 TRACE type.descriptor.sql.BasicBinder.bind:binding parameter [3] as [VARCHAR] - break
INFO:20.11. 2012 22:50:00,262 TRACE type.descriptor.sql.BasicBinder.bind:binding parameter [4] as [VARCHAR] - a@b.com
INFO:20.11.2012 22:50:00,264 DEBUG hibernate.jdbc.util.SQLStatementLogger .logStatement:从USER_TEAM中删除EMAIL =?
信息:休眠:从USER_TEAM删除EMAIL =?
INFO:20.11.2012 22:50:00,271 TRACE type.descriptor.sql.BasicBinder.bind:binding parameter [1] as [VARCHAR] - a@b.com

INFO:20.11.2012 22:50:00,274 DEBUG
org.hibernate .transaction.JDBCTransaction.toggleAutoCommit:重新启用自动提交信息:20.11.2012 22:50:00,274 DEBUG org.hibernate.transaction.JDBCTransaction.commit:已提交JDBC连接

更新操作由Spring的hibernateTemplate在UserDAO中的这个简单方法中提供:

public void saveUser(User user){
    hibernateTemplate.saveOrUpdate(user);
}    
Run Code Online (Sandbox Code Playgroud)

(我知道不应该使用hibernateTemplate,但我认为这不是这个问题的重点)

并且Spring服务bean UserServiceImpl在事务中简单地调用DAO方法:

@Transactional(readOnly=false)
public void saveUser(User user){
    userDao.saveUser(user);
}
Run Code Online (Sandbox Code Playgroud)


正如你所看到的,我没有任何级联注释,在更新中我当然不会改变用户的PK(EMAIL),所以我不明白这种行为.我正在使用spring 3.1.0.RELEASE和hibernate 3.6.10.Final.

感谢您的任何建议或解释.

JB *_*zet 5

您不需要任何级联来实现此目的.给定用户的连接表的内容teamList由该用户的集合的内容确定.因此,如果您saveOrUpdate()与具有空团队列表的用户呼叫,Hibernate将删除此用户的连接表的内容.