2

私のチームワーク指向のアプリでは、ユーザーとチームの間に多対多の関係があるため、休止状態は関連付けテーブルを作成します。問題は、チームを持つユーザーを更新した後、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: 現在の autocommit ステータス: 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: user_.EMAIL、user_.GROUPNAME を選択しますGROUPNAME0_ として、user_.NAME を NAME0_ として、user_.PASSWORD を PASSWORD0_ として USERS から user_ where user_.EMAIL=?
情報: 休止状態: user_.EMAIL、user_.GROUPNAME を GROUPNAME0_ として、user_.NAME を NAME0_ として、user_.PASSWORD を PASSWORD0_ として USERS user_ から選択します。user_.EMAIL=?
情報: 20.11.2012 22:50:00,176 TRACE type.descriptor.sql.BasicBinder.bind: パラメーター [1] を [VARCHAR] としてバインド - a@b.com
情報: 20.11.2012 22:50:00,177 TRACE type.descriptor .sql.BasicExtractor.extract: 列 [GROUPNAME0_] として [ユーザー] が見つかりました
情報: 20.11.2012 22:50:00,178 TRACE type.descriptor.sql.BasicExtractor.extract: 列 [NAME0_] として [デフォルト] が見つかりまし
た2012 22:50:00,178 トレース type.descriptor.sql.BasicExtractor.extract: [デフォルト] 列 [PASSWORD0_]
情報として見つかりました: 20.11.2012 22:50:00,251 DEBUG org.hibernate.transaction.JDBCTransaction.commit: コミット
情報: 20.11.2012 22:50:00,252 DEBUG hibernate.jdbc.util.SQLStatementLogger.logStatement: ユーザーを更新します GROUPNAME=?, NAME=?, PASSWORD=? メールアドレス=?
INFO: Hibernate: update USERS set GROUPNAME=?, NAME=?, PASSWORD=? メールアドレス=?
情報: 20.11.2012 22:50:00,260 TRACE type.descriptor.sql.BasicBinder.bind: パラメーター [1] を [VARCHAR] としてバインド - ユーザー
情報: 20.11.2012 22:50:00,261 TRACE type.descriptor.sql.BasicBinder .bind: パラメータ [2] を [VARCHAR] としてバインド - andy
INFO: 20.11.2012 22:50:00,261 TRACE type.descriptor.sql.BasicBinder.bind: パラメータ [3] を [VARCHAR] としてバインド - ブレーク
INFO: 20.11. 2012 22:50:00,262 TRACE type.descriptor.sql.BasicBinder.bind: パラメーター [4] を [VARCHAR] としてバインド - a@b.com
INFO: 20.11.2012 22:50:00,264 DEBUG hibernate.jdbc.util.SQLStatementLogger .logStatement: EMAIL=? の USER_TEAM から削除します。
情報: 休止状態: EMAIL=? の USER_TEAM から削除します
情報: 20.11.2012 22:50:00,271 TRACE type.descriptor.sql.BasicBinder.bind: パラメーター [1] を [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 を使用すべきではないことはわかっていますが、それはこの問題のポイントではないと思います)

また、DAO メソッドは、Spring サービス Bean UserServiceImpl によってトランザクションで呼び出されるだけです。

@Transactional(readOnly=false)
public void saveUser(User user){
    userDao.saveUser(user);
}


ご覧のとおり、カスケード注釈はありません。もちろん、更新時にユーザー (EMAIL) の PK を変更していないため、この動作がわかりません。春の 3.1.0.RELEASE と休止状態の 3.6.10.Final を使用しています。

提案や説明をありがとう。

4

1 に答える 1

5

これを行うためにカスケードは必要ありません。teamList特定のユーザーの結合テーブルの内容は、このユーザーのコレクションの内容によって決まります。したがってsaveOrUpdate()、空のチーム リストを持つユーザーで呼び出すと、Hibernate はこのユーザーの結合テーブルの内容を削除します。

于 2012-11-20T22:42:20.213 に答える