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

时间:2012-11-20 22:33:02

标签: hibernate many-to-many hibernate-annotations cascading-deletes hibernate-cascade

在我的面向团队的应用程序中,我在User和Team之间有多对多的关系,因此hibernate创建了关联表。问题是,在更新了具有Team的用户之后,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

这是日志:

  

INFO: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:当前自动提交状态:true
  信息:20.11.2012 22:50:00,175 DEBUG org.hibernate.transaction.JDBCTransaction.begin:禁用自动提交
  INFO:20.11.2012 22:50:00,175 DEBUG hibernate.jdbc.util.SQLStatementLogger.logStatement:从USERS user_中选择user_.EMAIL,user_.GROUPNAME为GROUPNAME0_,user_.NAME为NAME0_,user_.PASSWORD为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
  信息:20.11.2012 22:50:00,177 TRACE type.descriptor.sql.BasicExtractor.extract:找到[users]列[GROUPNAME0_]
  信息:20.11.2012 22:50:00,178 TRACE type.descriptor.sql.BasicExtractor.extract:找到[default]作为列[NAME0_]
  INFO:20.11.2012 22:50:00,178 TRACE type.descriptor.sql.BasicExtractor.extract:找到[default]作为列[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 =?的地方    INFO:Hibernate:更新USERS设置GROUPNAME =?,NAME =?,PASSWORD =?哪里有EMAIL =?
  INFO:20.11.2012 22:50:00,260 TRACE type.descriptor.sql.BasicBinder.bind:binding parameter [1] as [VARCHAR] - 用户
  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

  信息: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);
}    

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

在Spring事务服务bean UserServiceImpl:

中简单地在事务中调用DAO方法
@Transactional(readOnly=false)
public void saveUser(User user){
    userDao.saveUser(user);
}


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

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

1 个答案:

答案 0 :(得分:5)

你不需要任何级联来实现这一点。给定用户的连接表的内容由该用户的teamList集合的内容确定。因此,如果您使用具有空团队列表的用户调用saveOrUpdate(),Hibernate将删除此用户的连接表的内容。